From 05c81f6d17ac5c7a10406665c4a70af82a6ed7b6 Mon Sep 17 00:00:00 2001 From: Alexander Moibenko Date: Wed, 1 Aug 2018 10:48:36 -0500 Subject: [PATCH] MTX with library. Allows to call mtx routines. The rpm for this version must be built as: Replace mtx.spec in SPECS Put *.patch into SOURCES and build rpm. --- mtx-1.3.12/Makefile.in | 20 +- mtx-1.3.12/mtx.c | 27 +- mtx-1.3.12/mtx.spec | 10 +- mtx-1.3.12/mtxl.c | 145 ++-- .../patches/mtx-1.3.12-mtx-library.patch | 691 ++++++++++++++++++ 5 files changed, 805 insertions(+), 88 deletions(-) create mode 100644 mtx-1.3.12/patches/mtx-1.3.12-mtx-library.patch diff --git a/mtx-1.3.12/Makefile.in b/mtx-1.3.12/Makefile.in index 05894d2..18fc35b 100644 --- a/mtx-1.3.12/Makefile.in +++ b/mtx-1.3.12/Makefile.in @@ -3,16 +3,17 @@ # USE GMAKE, NOT REGULAR BSD MAKE!) # # Valid targets: -# linux86 freebsd86 solarissparc sgi dec vms +# linux86 freebsd86 solarissparc sgi dec vms # # Makefile changes by Lars Kellogg-Stedman for better integration with -# GNU Autoconf. +# GNU Autoconf. # Version # for 'make dist'... VERSION=1.3.12 BINS = mtx@EXEEXT@ tapeinfo@EXEEXT@ loaderinfo@EXEEXT@ scsitape@EXEEXT@ scsieject@EXEEXT@ EXTRA_BINS = nsmhack@EXEEXT@ +LIB=libmtx.a DBGS := $(BINS:%@EXEEXT@=%.dbg) MAN = mtx.1 tapeinfo.1 loaderinfo.1 scsitape.1 scsieject.1 MAN_HTML := $(MAN:%.1=%.html) @@ -46,7 +47,7 @@ VPATH = $(srcdir) # Linux on x86... # ifeq ($(TARGET),linux) -CFLAGS += -Wall +CFLAGS += -Wall -fpic -O3 CPPFLAGS += -DLONG_PRINT_REQUEST_SENSE=1 endif @@ -64,7 +65,7 @@ LIBS += -lcam endif ifeq ($(TARGET),hpux) -CFLAGS += -O -D_HPUX_SOURCE -D __hpux__ +CFLAGS += -O -D_HPUX_SOURCE -D __hpux__ endif # @@ -105,7 +106,7 @@ else strip $< -o $@ endif -all: $(BINS) +all: $(BINS) $(LIB) dbgs: $(DBGS) @@ -113,7 +114,7 @@ install: $(BINS) $(INSTALL_DIR) $(DESTDIR)$(sbindir) for file in $(BINS); do \ $(INSTALL_BIN) "$$file" $(DESTDIR)$(sbindir) ; \ - done + done $(INSTALL_DIR) $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1 for file in mtx.1 tapeinfo.1 scsitape.1 scsieject.1 loaderinfo.1 ; do \ $(INSTALL_DOC) "$$file" $(DESTDIR)$(mandir)/man1 ; \ @@ -132,7 +133,7 @@ distclean: clean rm -f Makefile config.h config.log config.cache config.status dist: distclean - ./makedist $(VERSION) + ./makedist $(VERSION) loaderinfo@EXEEXT@: loaderinfo.o mtxl.o mtxl.h mtx.h $(EXTRA) $(CC) $(LDFLAGS) -o loaderinfo@EXEEXT@ loaderinfo.o mtxl.o $(EXTRA) $(LIBS) @@ -143,7 +144,7 @@ nsmhack@EXEEXT@: nsmhack.o mtxl.o $(EXTRA) mtx@EXEEXT@: mtx.o mtxl.o mtxl.h mtx.h $(EXTRA) $(CC) $(LDFLAGS) -o mtx@EXEEXT@ mtx.o mtxl.o $(EXTRA) $(LIBS) -mam2debug@EXEEXT@: mtxl.o mam2debug.o mtx.h $(EXTRA) +mam2debug@EXEEXT@: mtxl.o mam2debug.o mtx.h $(EXTRA) $(CC) $(LDFLAGS) -o mam2debug@EXEEXT@ mtxl.o mam2debug.o $(EXTRA) $(LIBS) tapeinfo@EXEEXT@: tapeinfo.o mtxl.o mtx.h mtxl.h $(EXTRA) @@ -160,6 +161,9 @@ scsitape.o: scsitape.c mtx.h mtxl.h scsieject@EXEEXT@: scsieject.o mtxl.o mtxl.h mtx.h $(EXTRA) $(CC) $(LDFLAGS) -o scsieject@EXEEXT@ scsieject.o mtxl.o $(EXTRA) $(LIBS) +$(LIB): mtx.o mtxl.o + ar qvs contrib/$(LIB) mtx.o mtxl.o + $(CC) $(LDFLAGS) -shared -o contrib/libmtx.so mtx.o mtxl.o scsieject.o: scsieject.c mtx.h mtxl.h loaderinfo.o: loaderinfo.c mtx.h mtxl.h diff --git a/mtx-1.3.12/mtx.c b/mtx-1.3.12/mtx.c index fab11bb..e09d161 100644 --- a/mtx-1.3.12/mtx.c +++ b/mtx-1.3.12/mtx.c @@ -79,7 +79,8 @@ static char *PeripheralDeviceType[32] = static int argc; static char **argv; -static char *device=NULL; /* the device name passed as argument */ +char *device=NULL; /* the device name passed as argument */ +int absolute_addressing=0; /* if not 0 - use absolute adresses of storage and tranport elements as known to the robot */ /* Unfortunately this must be true for SGI, because SGI does not use an int :-(. @@ -496,14 +497,24 @@ static void Status(void) TransferElementNumber < ElementStatus->DataTransferElementCount; TransferElementNumber++) { - + if (absolute_addressing==0) { printf("Data Transfer Element %d:", TransferElementNumber); + } + else { + printf("Data Transfer Element %d :", ElementStatus->DataTransferElementAddress[TransferElementNumber]); + } if (ElementStatus->DataTransferElementFull[TransferElementNumber]) { if (ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber] > -1) { - printf("Full (Storage Element %d Loaded)", - ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber]+1); + if (absolute_addressing==0) { + printf("Full (Storage Element %d Loaded)", + ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber]+1); + } + else { + printf("Full (Storage Element %d Loaded)", + ElementStatus->StorageElementAddress[TransferElementNumber]); + } } else { @@ -531,9 +542,16 @@ static void Status(void) StorageElementNumber < ElementStatus->StorageElementCount; StorageElementNumber++) { + if (absolute_addressing==0) { printf( " Storage Element %d%s:%s", StorageElementNumber + 1, (ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "", (ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty")); + } + else { + printf( " Storage Element %d%s:%s", ElementStatus->StorageElementAddress[StorageElementNumber], + (ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "", + (ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty")); + } if (ElementStatus->PrimaryVolumeTag[StorageElementNumber][0]) { @@ -918,7 +936,6 @@ void execute_command(struct command_table_struct *command) } open_device(); } - if (!ElementStatus && command->need_status) { inquiry_info = RequestInquiry(MediumChangerFD,&RequestSense); diff --git a/mtx-1.3.12/mtx.spec b/mtx-1.3.12/mtx.spec index e2bf30d..1588025 100644 --- a/mtx-1.3.12/mtx.spec +++ b/mtx-1.3.12/mtx.spec @@ -1,6 +1,6 @@ Name: mtx Version: 1.3.12 -Release: 14%{?dist} +Release: 14fnal_p%{?dist} Summary: SCSI media changer control program License: GPLv2 Group: Applications/System @@ -14,6 +14,7 @@ Patch2: emc-fix-fail-with-too-high-slot-count_cleanupver.patch Patch3: mtx-1.3.12-fix-resource-leak.patch Patch4: mtx-1.3.12-scsitape-usage--add-erase.patch Patch5: mtx-1.3.12-man-Document-mtx-eject-and-previous-operations.patch +Patch6: mtx-1.3.12-mtx-library.patch URL: http://mtx.sourceforge.net/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -38,6 +39,7 @@ tape at a time, you should install MTX. %patch3 -p1 -b .fixresourceleak %patch4 -p1 -b .scsitape_adderase %patch5 -p1 -b .mtxman1upd +%patch6 -p2 -b .mtxlib # remove exec permission chmod a-x contrib/config_sgen_solaris.sh contrib/mtx-changer @@ -67,6 +69,8 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Tue Jul 31 2018 Alexander Moibenko - 1.3.12-14fnal_p +- Changes to allow to use mtx as library and show absolute transfer and storage elements as output of status call * Wed Mar 16 2016 David Sommerseth - 1.3.12-14 - Update scsitape --help screen to show the erase command and improved mtx.1 man page (#948459) @@ -220,14 +224,14 @@ rm -rf $RPM_BUILD_ROOT * Thu Jun 15 2000 Preston Brown - 1.2.7 -* Tue May 23 2000 Preston Brown +* Tue May 23 2000 Preston Brown - adopted for Winston * Fri May 12 2000 Kenneth Porter - 1.2.6 - Fixed 'eepos' stuff to use | rather than || (whoops!) - Accept a 4-byte element descriptor for the robot arm for certain older -- autochangers. +- autochangers. * Mon May 8 2000 Kenneth Porter - Spell sourceforge right so the link at rpmfind.net will work. diff --git a/mtx-1.3.12/mtxl.c b/mtx-1.3.12/mtxl.c index c468f88..5e3b921 100644 --- a/mtx-1.3.12/mtxl.c +++ b/mtx-1.3.12/mtxl.c @@ -23,7 +23,7 @@ /* * FatalError: changed Feb. 2000 elg@badtux.org to eliminate a buffer - * overflow :-(. That could be important if mtxl is SUID for some reason. + * overflow :-(. That could be important if mtxl is SUID for some reason. */ #include "mtx.h" @@ -34,7 +34,7 @@ /* #define DEBUG_MODE_SENSE 1 */ /* #define DEBUG */ /* #define DEBUG_SCSI */ -#define __WEIRD_CHAR_SUPPRESS 1 +#define __WEIRD_CHAR_SUPPRESS 1 /* zap the following define when we finally add real import/export support */ #define IMPORT_EXPORT_HACK 1 /* for the moment, import/export == storage */ @@ -100,7 +100,7 @@ Inquiry_T *RequestInquiry(DEVICE_TYPE fd, RequestSense_T *RequestSense) Inquiry_T *Inquiry; CDB_T CDB; - Inquiry = (Inquiry_T *) xmalloc(sizeof(Inquiry_T)); + Inquiry = (Inquiry_T *) xmalloc(sizeof(Inquiry_T)); CDB[0] = 0x12; /* INQUIRY */ CDB[1] = 0; /* EVPD = 0 */ @@ -231,7 +231,8 @@ void FatalError(char *ErrorMessage, ...) va_end(ArgumentPointer); #ifndef VMS - exit(1); + //exit(1); + return; /* if used as library routine it can not exit, because this would terminate the caller */ #else sys$exit(VMS_ExitCode); #endif @@ -280,10 +281,10 @@ int max(int x, int y) /* Okay, this is a hack for the NSM modular jukebox series, which - * uses the "SEND DIAGNOSTIC" command to do shit. + * uses the "SEND DIAGNOSTIC" command to do shit. */ -int SendNSMHack(DEVICE_TYPE MediumChangerFD, NSM_Param_T *nsm_command, +int SendNSMHack(DEVICE_TYPE MediumChangerFD, NSM_Param_T *nsm_command, int param_len, int timeout) { CDB_T CDB; @@ -362,7 +363,7 @@ NSM_Result_T *RecNSMHack( DEVICE_TYPE MediumChangerFD, /* Routine to inventory the library. Needed by, e.g., some Breece Hill * loaders. Sends an INITIALIZE_ELEMENT_STATUS command. This command - * has no parameters, such as a range to scan :-(. + * has no parameters, such as a range to scan :-(. */ int Inventory(DEVICE_TYPE MediumChangerFD) @@ -370,7 +371,7 @@ int Inventory(DEVICE_TYPE MediumChangerFD) CDB_T CDB; /* okay, now for the command: */ - CDB[0] = 0x07; + CDB[0] = 0x07; CDB[1] = CDB[2] = CDB[3] = CDB[4] = CDB[5] = 0; /* set us a very long timeout, sigh... */ @@ -394,8 +395,8 @@ int Inventory(DEVICE_TYPE MediumChangerFD) /* Routine to read the Mode Sense Element Address Assignment Page */ /* We try to read the page. If we can't read the page, we return NULL. * Our caller really isn't too worried about why we could not read the - * page, it will simply default to some kind of default values. - */ + * page, it will simply default to some kind of default values. + */ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD) { CDB_T CDB; @@ -405,7 +406,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD) /* okay, now for the command: */ CDB[0] = 0x1A; /* Mode Sense(6) */ - CDB[1] = 0x08; + CDB[1] = 0x08; CDB[2] = 0x1D; /* Mode Sense Element Address Assignment Page */ CDB[3] = 0; CDB[4] = 136; /* allocation_length... */ @@ -482,7 +483,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD) ((int)sense_page->NumStorageHi << 8) + sense_page->NumStorageLo; retval->ImportExportStart = - ((int)sense_page->ImportExportStartHi << 8) + sense_page->ImportExportStartLo; + ((int)sense_page->ImportExportStartHi << 8) + sense_page->ImportExportStartLo; retval->NumImportExport = ((int)sense_page->NumImportExportHi << 8) + sense_page->NumImportExportLo; @@ -494,7 +495,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD) ((int)sense_page->NumDataTransferHi << 8) + sense_page->NumDataTransferLo; /* allocate a couple spares 'cause some HP autochangers and maybe others - * don't properly report the robotics arm(s) count here... + * don't properly report the robotics arm(s) count here... */ retval->NumElements = retval->NumStorage+retval->NumImportExport + @@ -549,7 +550,7 @@ static ElementStatus_T *AllocateElementData(ElementModeSense_T *mode_sense) retval->DataTransferElementAddress = (int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1)); - retval->DataTransferElementSourceStorageElementNumber = + retval->DataTransferElementSourceStorageElementNumber = (int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1)); retval->DataTransferPrimaryVolumeTag = (barcode *)xzmalloc(sizeof(barcode) * (mode_sense->NumDataTransfer + 1)); @@ -587,14 +588,14 @@ void copy_barcode(unsigned char *src, unsigned char *dest) dest++; } - *dest = 0; /* null-terminate */ + *dest = 0; /* null-terminate */ } /* This #%!@# routine has more parameters than I can count! */ static unsigned char *SendElementStatusRequestActual( DEVICE_TYPE MediumChangerFD, RequestSense_T *RequestSense, - Inquiry_T *inquiry_info, + Inquiry_T *inquiry_info, SCSI_Flags_T *flags, int ElementStart, int NumElements, @@ -609,7 +610,7 @@ static unsigned char *SendElementStatusRequestActual( #ifdef HAVE_GET_ID_LUN scsi_id_t *scsi_id; #endif - if (inquiry_info->MChngr && + if (inquiry_info->MChngr && inquiry_info->PeripheralDeviceType != MEDIUM_CHANGER_TYPE) { is_attached = true; @@ -617,7 +618,7 @@ static unsigned char *SendElementStatusRequestActual( if (flags->no_attached) { - /* override, sigh */ + /* override, sigh */ is_attached = false; } @@ -633,11 +634,11 @@ static unsigned char *SendElementStatusRequestActual( if (is_attached) { - CDB[0] = 0xB4; /* whoops, READ_ELEMENT_STATUS_ATTACHED! */ + CDB[0] = 0xB4; /* whoops, READ_ELEMENT_STATUS_ATTACHED! */ } #ifdef HAVE_GET_ID_LUN - CDB[1] = (scsi_id->lun << 5) | ((flags->no_barcodes) ? + CDB[1] = (scsi_id->lun << 5) | ((flags->no_barcodes) ? 0 : 0x10) | flags->elementtype; /* Lun + VolTag + Type code */ free(scsi_id); #else @@ -677,7 +678,7 @@ static unsigned char *SendElementStatusRequestActual( /* First see if we have sense key of 'illegal request', - additional sense code of '24', additional sense qualfier of + additional sense code of '24', additional sense qualfier of '0', and field in error of '4'. This means that we issued a request w/bar code reader and did not have one, thus must re-issue the request w/out barcode :-(. @@ -722,14 +723,14 @@ static unsigned char *SendElementStatusRequestActual( PrintRequestSense(RequestSense); /* see what it sez :-(. */ fprintf(stderr,"Data:\n"); PrintHex(2, DataBuffer, 40); -#endif +#endif return DataBuffer; /* we succeeded! */ } unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD, RequestSense_T *RequestSense, - Inquiry_T *inquiry_info, + Inquiry_T *inquiry_info, SCSI_Flags_T *flags, int ElementStart, int NumElements, @@ -750,7 +751,7 @@ unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD, /* One weird loader wants either 8 or BYTE_COUNT_OF_REPORT values for the ALLOCATION_LENGTH. Give it what it wants - if we get an Sense Key of 05 Illegal Request with a + if we get an Sense Key of 05 Illegal Request with a CDB position of 7 as the field in error. */ @@ -882,7 +883,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, { /* TransportElementDescriptor = (TransportElementDescriptor_T *) DataPointer; */ - memcpy(&TEBuf, DataPointer, + memcpy(&TEBuf, DataPointer, (TransportElementDescriptorLength <= sizeof(TEBuf)) ? TransportElementDescriptorLength : sizeof(TEBuf)); @@ -909,7 +910,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, case MediumTransportElement: ElementStatus->TransportElementAddress = BigEndian16(TransportElementDescriptor->ElementAddress); #ifdef DEBUG - fprintf(stderr,"TransportElementAddress=%d\n",ElementStatus->TransportElementAddress); + fprintf(stderr,"TransportElementAddress=%d\n",ElementStatus->TransportElementAddress); #endif break; @@ -936,7 +937,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, ElementStatus->StorageElementFull[ImportExportIndex] = TransportElementDescriptor->Full; - if ( (TransportElementDescriptorLength > 11) && + if ( (TransportElementDescriptorLength > 11) && (ElementStatusPage->VolBits & E2_AVOLTAG)) { copy_barcode(TransportElementDescriptor->AlternateVolumeTag, @@ -945,8 +946,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, else { ElementStatus->AlternateVolumeTag[ImportExportIndex][0] = 0; /* null string. */; - } - if ((TransportElementDescriptorLength > 11) && + } + if ((TransportElementDescriptorLength > 11) && (ElementStatusPage->VolBits & E2_PVOLTAG)) { copy_barcode(TransportElementDescriptor->PrimaryVolumeTag, @@ -967,8 +968,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, fprintf(stderr,"StorageElementCount=%d ElementAddress = %d ",ElementStatus->StorageElementCount,BigEndian16(TransportElementDescriptor->ElementAddress)); #endif /* ATL/Exabyte kludge -- skip slots that aren't installed :-( */ - if (TransportElementDescriptor->AdditionalSenseCode==0x83 && - TransportElementDescriptor->AdditionalSenseCodeQualifier==0x02) + if (TransportElementDescriptor->AdditionalSenseCode==0x83 && + TransportElementDescriptor->AdditionalSenseCodeQualifier==0x02) continue; ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount] = @@ -986,7 +987,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, ElementStatus->StorageElementCount; /* slot idx. */ /* ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount]; */ } - if ((TransportElementDescriptorLength > 11) && + if ((TransportElementDescriptorLength > 11) && (ElementStatusPage->VolBits & E2_AVOLTAG)) { copy_barcode(TransportElementDescriptor->AlternateVolumeTag, @@ -995,8 +996,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, else { ElementStatus->AlternateVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */; - } - if ((TransportElementDescriptorLength > 11) && + } + if ((TransportElementDescriptorLength > 11) && (ElementStatusPage->VolBits & E2_PVOLTAG)) { copy_barcode(TransportElementDescriptor->PrimaryVolumeTag, @@ -1009,9 +1010,9 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, ElementStatus->StorageElementCount++; /* - Note that the original mtx had no check here for + Note that the original mtx had no check here for buffer overflow, though some drives might mistakingly - do one... + do one... */ if (ElementStatus->StorageElementCount > mode_sense->NumStorage) @@ -1033,33 +1034,33 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, report that they have a 2nd tape drive when they don't. We could generalize this in an ideal world, but my attempt to do so failed with dual-drive Exabyte tape libraries that - *DID* have the second drive. Sigh. + *DID* have the second drive. Sigh. */ - if (TransportElementDescriptor->AdditionalSenseCode==0x83 && + if (TransportElementDescriptor->AdditionalSenseCode==0x83 && TransportElementDescriptor->AdditionalSenseCodeQualifier==0x04) { continue; } /* generalize it. Does it work? Let's try it! */ - /* + /* No, dammit, following does not work on dual-drive Exabyte 'cause if a tape is in the drive, it sets the AdditionalSense code to something (sigh). */ /* if (TransportElementDescriptor->AdditionalSenseCode!=0) continue; - */ + */ ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount] = BigEndian16(TransportElementDescriptor->ElementAddress); - ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount] = + ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount] = TransportElementDescriptor->Full; ElementStatus->DataTransferElementSourceStorageElementNumber[ElementStatus->DataTransferElementCount] = BigEndian16(TransportElementDescriptor->SourceStorageElementAddress); #ifdef DEBUG - fprintf(stderr, "%d: ElementAddress = %d, Full = %d, SourceElement = %d\n", + fprintf(stderr, "%d: ElementAddress = %d, Full = %d, SourceElement = %d\n", ElementStatus->DataTransferElementCount, ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount], ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount], @@ -1118,17 +1119,17 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, /* * We no longer do the funky trick to figure out ALLOCATION_LENGTH. * Instead, we use the SCSI Generic command rather than SEND_SCSI_COMMAND - * under Linux, which gets around the @#%@ 4k buffer size in Linux. + * under Linux, which gets around the @#%@ 4k buffer size in Linux. * We still have the restriction that Linux cuts off the last two * bytes of the SENSE DATA (Q#@$%@#$^ Linux!). Which means that the - * verbose widget won't work :-(. - + * verbose widget won't work :-(. + * We now look for that "attached" bit in the inquiry_info to see whether * to use READ_ELEMENT_ATTACHED or plain old READ_ELEMENT. In addition, we * look at the device type in the inquiry_info to see whether it is a media * changer or tape device, and if it's a media changer device, we ignore the * attached bit (one beta tester found an old 4-tape DAT changer that set - * the attached bit for both the tape device AND the media changer device). + * the attached bit for both the tape device AND the media changer device). */ @@ -1155,7 +1156,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * if (flags->no_attached) { - /* override, sigh */ + /* override, sigh */ is_attached = false; } @@ -1185,7 +1186,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * ElementStatus->DataTransferElementCount = 0; /* first, allocate some empty storage stuff: Note that we pass this - * down to ParseElementStatus (sigh!) + * down to ParseElementStatus (sigh!) */ EmptyStorageElementAddress = (int *)xzmalloc((mode_sense->NumStorage+1)*sizeof(int)); @@ -1202,7 +1203,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * for (i = 0; i < mode_sense->NumDataTransfer; i++) { /* initialize them to an illegal # so that we can fix later... */ - ElementStatus->DataTransferElementSourceStorageElementNumber[i] = -1; + ElementStatus->DataTransferElementSourceStorageElementNumber[i] = -1; } if (flags->querytype == MTX_ELEMENTSTATUS_ORIGINAL) @@ -1308,7 +1309,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * PrintRequestSense(RequestSense); #endif FreeElementData(ElementStatus); - return NULL; + return NULL; } #ifdef DEBUG @@ -1323,7 +1324,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * /* grr, damned brain dead HP doesn't report that it has any! */ if (!mode_sense->NumMediumTransport) - { + { ElementStatus->TransportElementAddress = 0; /* default it sensibly :-(. */ } else @@ -1347,8 +1348,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * PrintRequestSense(RequestSense); #endif FreeElementData(ElementStatus); - return NULL; - } + return NULL; + } #ifdef DEBUG fprintf(stderr,"Parsing robot arm data\n"); #endif @@ -1366,8 +1367,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * fprintf(stderr,"Using alternative element status polling method (all elements)\n"); #endif /* ----------------- ALL Elements ---------------------- */ - /* Just keep asking for elements till no more are returned - - increment our starting address as we go acording to the + /* Just keep asking for elements till no more are returned + - increment our starting address as we go acording to the number of elements returned from the last call */ @@ -1384,7 +1385,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * mode_sense->MaxReadElementStatusData); if (!DataBuffer) { - if (RequestSense->AdditionalSenseCode == 0x21 && + if (RequestSense->AdditionalSenseCode == 0x21 && RequestSense->AdditionalSenseCodeQualifier == 0x01) { /* Error is invalid element address, we've probably just hit the end */ @@ -1393,8 +1394,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * /* darn. Free up stuff and return. */ FreeElementData(ElementStatus); - return NULL; - } + return NULL; + } nLastEl = nNextEl; @@ -1423,7 +1424,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * * * Pass1: * Translate from raw element # to our translated # (if possible). - * First, check the SourceStorageElementNumbers against the list of + * First, check the SourceStorageElementNumbers against the list of * filled slots. If the slots indicated are empty, we accept that list as * valid. Otherwise decide the SourceStorageElementNumbers are invalid. * @@ -1432,7 +1433,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * * then we must search for free slots, and assign SourceStorageElementNumbers * to those free slots. We happen to already built a list of free * slots as part of the process of reading the storage element numbers - * from the tape. So that's easy enough to do! + * from the tape. So that's easy enough to do! */ #ifdef DEBUG_TAPELIST @@ -1448,7 +1449,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * /* * Now we re-assign origin slots if the "real" origin slot - * is obviously defective: + * is obviously defective: */ /* pass one: */ for (i = 0; i < ElementStatus->DataTransferElementCount; i++) @@ -1486,12 +1487,12 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * * drives will be assigned a -1 (see the initialization loop for * EmptyStorageElementAddress above), which will be reported as "slot 0" * by the user interface. This is an invalid value, but more useful for us - * to have than just crapping out here :-(. + * to have than just crapping out here :-(. */ empty_idx=0; for (i = 0; i < ElementStatus->DataTransferElementCount; i++) { - if (ElementStatus->DataTransferElementFull[i] && + if (ElementStatus->DataTransferElementFull[i] && ElementStatus->DataTransferElementSourceStorageElementNumber[i] < 0) { #ifdef DEBUG_TAPELIST @@ -1543,7 +1544,7 @@ RequestSense_T *PositionElement(DEVICE_TYPE MediumChangerFD, /* Now the actual media movement routine! */ RequestSense_T *MoveMedium( DEVICE_TYPE MediumChangerFD, int SourceAddress, - int DestinationAddress, + int DestinationAddress, ElementStatus_T *ElementStatus, Inquiry_T *inquiry_info, SCSI_Flags_T *flags) { @@ -1646,7 +1647,7 @@ RequestSense_T *ExchangeMedium( DEVICE_TYPE MediumChangerFD, int SourceAddress, #ifdef DEBUG_EXCHANGE dump_cdb(&CDB,12); -#endif +#endif if (SCSI_ExecuteCommand(MediumChangerFD, Output, &CDB, 12, NULL, 0, RequestSense) != 0) @@ -1690,8 +1691,8 @@ RequestSense_T *Erase(DEVICE_TYPE MediumChangerFD) return NULL; /* Success! */ } -/* Routine to send an LOAD/UNLOAD from the MMC/SSC spec to a device. - * For tapes and changers this can be used either to eject a tape +/* Routine to send an LOAD/UNLOAD from the MMC/SSC spec to a device. + * For tapes and changers this can be used either to eject a tape * or to eject a magazine (on some Seagate changers, when sent to LUN 1 ). * For CD/DVDs this is used to Load or Unload a disc which is required by * some media changers. @@ -1721,8 +1722,8 @@ int LoadUnload(DEVICE_TYPE fd, int bLoad) return 0; /* did do! */ } -/* Routine to send an START/STOP from the MMC/SSC spec to a device. - * For tape drives this may be required prior to using the changer +/* Routine to send an START/STOP from the MMC/SSC spec to a device. + * For tape drives this may be required prior to using the changer * Load or Unload commands. * For CD/DVD drives this is used to Load or Unload a disc which may be * required by some media changers. @@ -1746,9 +1747,9 @@ int StartStop(DEVICE_TYPE fd, int bStart) return 0; /* did do! */ } -/* Routine to send a LOCK/UNLOCK from the SSC/MMC spec to a device. +/* Routine to send a LOCK/UNLOCK from the SSC/MMC spec to a device. * This can be used to prevent or allow the Tape or CD/DVD from being - * removed. + * removed. */ int LockUnlock(DEVICE_TYPE fd, int bLock) @@ -1876,7 +1877,7 @@ void PrintRequestSense(RequestSense_T *RequestSense) fprintf(stderr, "mtx: Request Sense: Valid Residual=%s\n", RequestSense->Valid ? Yes : No); if (RequestSense->ErrorCode == 0x70) - { + { msg = "Current" ; } else if (RequestSense->ErrorCode == 0x71) diff --git a/mtx-1.3.12/patches/mtx-1.3.12-mtx-library.patch b/mtx-1.3.12/patches/mtx-1.3.12-mtx-library.patch new file mode 100644 index 0000000..07bcf98 --- /dev/null +++ b/mtx-1.3.12/patches/mtx-1.3.12-mtx-library.patch @@ -0,0 +1,691 @@ +diff --git a/mtx-1.3.12/Makefile.in b/mtx-1.3.12/Makefile.in +index 05894d2..18fc35b 100644 +--- a/mtx-1.3.12/Makefile.in ++++ b/mtx-1.3.12/Makefile.in +@@ -3,16 +3,17 @@ + # USE GMAKE, NOT REGULAR BSD MAKE!) + # + # Valid targets: +-# linux86 freebsd86 solarissparc sgi dec vms ++# linux86 freebsd86 solarissparc sgi dec vms + # + # Makefile changes by Lars Kellogg-Stedman for better integration with +-# GNU Autoconf. ++# GNU Autoconf. + + # Version # for 'make dist'... + VERSION=1.3.12 + + BINS = mtx@EXEEXT@ tapeinfo@EXEEXT@ loaderinfo@EXEEXT@ scsitape@EXEEXT@ scsieject@EXEEXT@ + EXTRA_BINS = nsmhack@EXEEXT@ ++LIB=libmtx.a + DBGS := $(BINS:%@EXEEXT@=%.dbg) + MAN = mtx.1 tapeinfo.1 loaderinfo.1 scsitape.1 scsieject.1 + MAN_HTML := $(MAN:%.1=%.html) +@@ -46,7 +47,7 @@ VPATH = $(srcdir) + # Linux on x86... + # + ifeq ($(TARGET),linux) +-CFLAGS += -Wall ++CFLAGS += -Wall -fpic -O3 + CPPFLAGS += -DLONG_PRINT_REQUEST_SENSE=1 + endif + +@@ -64,7 +65,7 @@ LIBS += -lcam + endif + + ifeq ($(TARGET),hpux) +-CFLAGS += -O -D_HPUX_SOURCE -D __hpux__ ++CFLAGS += -O -D_HPUX_SOURCE -D __hpux__ + endif + + # +@@ -105,7 +106,7 @@ else + strip $< -o $@ + endif + +-all: $(BINS) ++all: $(BINS) $(LIB) + + dbgs: $(DBGS) + +@@ -113,7 +114,7 @@ install: $(BINS) + $(INSTALL_DIR) $(DESTDIR)$(sbindir) + for file in $(BINS); do \ + $(INSTALL_BIN) "$$file" $(DESTDIR)$(sbindir) ; \ +- done ++ done + $(INSTALL_DIR) $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1 + for file in mtx.1 tapeinfo.1 scsitape.1 scsieject.1 loaderinfo.1 ; do \ + $(INSTALL_DOC) "$$file" $(DESTDIR)$(mandir)/man1 ; \ +@@ -132,7 +133,7 @@ distclean: clean + rm -f Makefile config.h config.log config.cache config.status + + dist: distclean +- ./makedist $(VERSION) ++ ./makedist $(VERSION) + + loaderinfo@EXEEXT@: loaderinfo.o mtxl.o mtxl.h mtx.h $(EXTRA) + $(CC) $(LDFLAGS) -o loaderinfo@EXEEXT@ loaderinfo.o mtxl.o $(EXTRA) $(LIBS) +@@ -143,7 +144,7 @@ nsmhack@EXEEXT@: nsmhack.o mtxl.o $(EXTRA) + mtx@EXEEXT@: mtx.o mtxl.o mtxl.h mtx.h $(EXTRA) + $(CC) $(LDFLAGS) -o mtx@EXEEXT@ mtx.o mtxl.o $(EXTRA) $(LIBS) + +-mam2debug@EXEEXT@: mtxl.o mam2debug.o mtx.h $(EXTRA) ++mam2debug@EXEEXT@: mtxl.o mam2debug.o mtx.h $(EXTRA) + $(CC) $(LDFLAGS) -o mam2debug@EXEEXT@ mtxl.o mam2debug.o $(EXTRA) $(LIBS) + + tapeinfo@EXEEXT@: tapeinfo.o mtxl.o mtx.h mtxl.h $(EXTRA) +@@ -160,6 +161,9 @@ scsitape.o: scsitape.c mtx.h mtxl.h + scsieject@EXEEXT@: scsieject.o mtxl.o mtxl.h mtx.h $(EXTRA) + $(CC) $(LDFLAGS) -o scsieject@EXEEXT@ scsieject.o mtxl.o $(EXTRA) $(LIBS) + ++$(LIB): mtx.o mtxl.o ++ ar qvs contrib/$(LIB) mtx.o mtxl.o ++ $(CC) $(LDFLAGS) -shared -o contrib/libmtx.so mtx.o mtxl.o + scsieject.o: scsieject.c mtx.h mtxl.h + + loaderinfo.o: loaderinfo.c mtx.h mtxl.h +diff --git a/mtx-1.3.12/mtx.c b/mtx-1.3.12/mtx.c +index fab11bb..e09d161 100644 +--- a/mtx-1.3.12/mtx.c ++++ b/mtx-1.3.12/mtx.c +@@ -79,7 +79,8 @@ static char *PeripheralDeviceType[32] = + static int argc; + static char **argv; + +-static char *device=NULL; /* the device name passed as argument */ ++char *device=NULL; /* the device name passed as argument */ ++int absolute_addressing=0; /* if not 0 - use absolute adresses of storage and tranport elements as known to the robot */ + + /* Unfortunately this must be true for SGI, because SGI does not + use an int :-(. +@@ -496,14 +497,24 @@ static void Status(void) + TransferElementNumber < ElementStatus->DataTransferElementCount; + TransferElementNumber++) + { +- ++ if (absolute_addressing==0) { + printf("Data Transfer Element %d:", TransferElementNumber); ++ } ++ else { ++ printf("Data Transfer Element %d :", ElementStatus->DataTransferElementAddress[TransferElementNumber]); ++ } + if (ElementStatus->DataTransferElementFull[TransferElementNumber]) + { + if (ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber] > -1) + { +- printf("Full (Storage Element %d Loaded)", +- ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber]+1); ++ if (absolute_addressing==0) { ++ printf("Full (Storage Element %d Loaded)", ++ ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber]+1); ++ } ++ else { ++ printf("Full (Storage Element %d Loaded)", ++ ElementStatus->StorageElementAddress[TransferElementNumber]); ++ } + } + else + { +@@ -531,9 +542,16 @@ static void Status(void) + StorageElementNumber < ElementStatus->StorageElementCount; + StorageElementNumber++) + { ++ if (absolute_addressing==0) { + printf( " Storage Element %d%s:%s", StorageElementNumber + 1, + (ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "", + (ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty")); ++ } ++ else { ++ printf( " Storage Element %d%s:%s", ElementStatus->StorageElementAddress[StorageElementNumber], ++ (ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "", ++ (ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty")); ++ } + + if (ElementStatus->PrimaryVolumeTag[StorageElementNumber][0]) + { +@@ -918,7 +936,6 @@ void execute_command(struct command_table_struct *command) + } + open_device(); + } +- + if (!ElementStatus && command->need_status) + { + inquiry_info = RequestInquiry(MediumChangerFD,&RequestSense); +diff --git a/mtx-1.3.12/mtxl.c b/mtx-1.3.12/mtxl.c +index c468f88..5e3b921 100644 +--- a/mtx-1.3.12/mtxl.c ++++ b/mtx-1.3.12/mtxl.c +@@ -23,7 +23,7 @@ + + /* + * FatalError: changed Feb. 2000 elg@badtux.org to eliminate a buffer +- * overflow :-(. That could be important if mtxl is SUID for some reason. ++ * overflow :-(. That could be important if mtxl is SUID for some reason. + */ + + #include "mtx.h" +@@ -34,7 +34,7 @@ + /* #define DEBUG_MODE_SENSE 1 */ + /* #define DEBUG */ + /* #define DEBUG_SCSI */ +-#define __WEIRD_CHAR_SUPPRESS 1 ++#define __WEIRD_CHAR_SUPPRESS 1 + + /* zap the following define when we finally add real import/export support */ + #define IMPORT_EXPORT_HACK 1 /* for the moment, import/export == storage */ +@@ -100,7 +100,7 @@ Inquiry_T *RequestInquiry(DEVICE_TYPE fd, RequestSense_T *RequestSense) + Inquiry_T *Inquiry; + CDB_T CDB; + +- Inquiry = (Inquiry_T *) xmalloc(sizeof(Inquiry_T)); ++ Inquiry = (Inquiry_T *) xmalloc(sizeof(Inquiry_T)); + + CDB[0] = 0x12; /* INQUIRY */ + CDB[1] = 0; /* EVPD = 0 */ +@@ -231,7 +231,8 @@ void FatalError(char *ErrorMessage, ...) + va_end(ArgumentPointer); + + #ifndef VMS +- exit(1); ++ //exit(1); ++ return; /* if used as library routine it can not exit, because this would terminate the caller */ + #else + sys$exit(VMS_ExitCode); + #endif +@@ -280,10 +281,10 @@ int max(int x, int y) + + + /* Okay, this is a hack for the NSM modular jukebox series, which +- * uses the "SEND DIAGNOSTIC" command to do shit. ++ * uses the "SEND DIAGNOSTIC" command to do shit. + */ + +-int SendNSMHack(DEVICE_TYPE MediumChangerFD, NSM_Param_T *nsm_command, ++int SendNSMHack(DEVICE_TYPE MediumChangerFD, NSM_Param_T *nsm_command, + int param_len, int timeout) + { + CDB_T CDB; +@@ -362,7 +363,7 @@ NSM_Result_T *RecNSMHack( DEVICE_TYPE MediumChangerFD, + + /* Routine to inventory the library. Needed by, e.g., some Breece Hill + * loaders. Sends an INITIALIZE_ELEMENT_STATUS command. This command +- * has no parameters, such as a range to scan :-(. ++ * has no parameters, such as a range to scan :-(. + */ + + int Inventory(DEVICE_TYPE MediumChangerFD) +@@ -370,7 +371,7 @@ int Inventory(DEVICE_TYPE MediumChangerFD) + CDB_T CDB; + + /* okay, now for the command: */ +- CDB[0] = 0x07; ++ CDB[0] = 0x07; + CDB[1] = CDB[2] = CDB[3] = CDB[4] = CDB[5] = 0; + + /* set us a very long timeout, sigh... */ +@@ -394,8 +395,8 @@ int Inventory(DEVICE_TYPE MediumChangerFD) + /* Routine to read the Mode Sense Element Address Assignment Page */ + /* We try to read the page. If we can't read the page, we return NULL. + * Our caller really isn't too worried about why we could not read the +- * page, it will simply default to some kind of default values. +- */ ++ * page, it will simply default to some kind of default values. ++ */ + ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD) + { + CDB_T CDB; +@@ -405,7 +406,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD) + + /* okay, now for the command: */ + CDB[0] = 0x1A; /* Mode Sense(6) */ +- CDB[1] = 0x08; ++ CDB[1] = 0x08; + CDB[2] = 0x1D; /* Mode Sense Element Address Assignment Page */ + CDB[3] = 0; + CDB[4] = 136; /* allocation_length... */ +@@ -482,7 +483,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD) + ((int)sense_page->NumStorageHi << 8) + sense_page->NumStorageLo; + + retval->ImportExportStart = +- ((int)sense_page->ImportExportStartHi << 8) + sense_page->ImportExportStartLo; ++ ((int)sense_page->ImportExportStartHi << 8) + sense_page->ImportExportStartLo; + + retval->NumImportExport = + ((int)sense_page->NumImportExportHi << 8) + sense_page->NumImportExportLo; +@@ -494,7 +495,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD) + ((int)sense_page->NumDataTransferHi << 8) + sense_page->NumDataTransferLo; + + /* allocate a couple spares 'cause some HP autochangers and maybe others +- * don't properly report the robotics arm(s) count here... ++ * don't properly report the robotics arm(s) count here... + */ + retval->NumElements = + retval->NumStorage+retval->NumImportExport + +@@ -549,7 +550,7 @@ static ElementStatus_T *AllocateElementData(ElementModeSense_T *mode_sense) + + retval->DataTransferElementAddress = + (int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1)); +- retval->DataTransferElementSourceStorageElementNumber = ++ retval->DataTransferElementSourceStorageElementNumber = + (int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1)); + retval->DataTransferPrimaryVolumeTag = + (barcode *)xzmalloc(sizeof(barcode) * (mode_sense->NumDataTransfer + 1)); +@@ -587,14 +588,14 @@ void copy_barcode(unsigned char *src, unsigned char *dest) + + dest++; + } +- *dest = 0; /* null-terminate */ ++ *dest = 0; /* null-terminate */ + } + + /* This #%!@# routine has more parameters than I can count! */ + static unsigned char *SendElementStatusRequestActual( + DEVICE_TYPE MediumChangerFD, + RequestSense_T *RequestSense, +- Inquiry_T *inquiry_info, ++ Inquiry_T *inquiry_info, + SCSI_Flags_T *flags, + int ElementStart, + int NumElements, +@@ -609,7 +610,7 @@ static unsigned char *SendElementStatusRequestActual( + #ifdef HAVE_GET_ID_LUN + scsi_id_t *scsi_id; + #endif +- if (inquiry_info->MChngr && ++ if (inquiry_info->MChngr && + inquiry_info->PeripheralDeviceType != MEDIUM_CHANGER_TYPE) + { + is_attached = true; +@@ -617,7 +618,7 @@ static unsigned char *SendElementStatusRequestActual( + + if (flags->no_attached) + { +- /* override, sigh */ ++ /* override, sigh */ + is_attached = false; + } + +@@ -633,11 +634,11 @@ static unsigned char *SendElementStatusRequestActual( + + if (is_attached) + { +- CDB[0] = 0xB4; /* whoops, READ_ELEMENT_STATUS_ATTACHED! */ ++ CDB[0] = 0xB4; /* whoops, READ_ELEMENT_STATUS_ATTACHED! */ + } + + #ifdef HAVE_GET_ID_LUN +- CDB[1] = (scsi_id->lun << 5) | ((flags->no_barcodes) ? ++ CDB[1] = (scsi_id->lun << 5) | ((flags->no_barcodes) ? + 0 : 0x10) | flags->elementtype; /* Lun + VolTag + Type code */ + free(scsi_id); + #else +@@ -677,7 +678,7 @@ static unsigned char *SendElementStatusRequestActual( + + /* + First see if we have sense key of 'illegal request', +- additional sense code of '24', additional sense qualfier of ++ additional sense code of '24', additional sense qualfier of + '0', and field in error of '4'. This means that we issued a request + w/bar code reader and did not have one, thus must re-issue the request + w/out barcode :-(. +@@ -722,14 +723,14 @@ static unsigned char *SendElementStatusRequestActual( + PrintRequestSense(RequestSense); /* see what it sez :-(. */ + fprintf(stderr,"Data:\n"); + PrintHex(2, DataBuffer, 40); +-#endif ++#endif + return DataBuffer; /* we succeeded! */ + } + + + unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD, + RequestSense_T *RequestSense, +- Inquiry_T *inquiry_info, ++ Inquiry_T *inquiry_info, + SCSI_Flags_T *flags, + int ElementStart, + int NumElements, +@@ -750,7 +751,7 @@ unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD, + /* + One weird loader wants either 8 or BYTE_COUNT_OF_REPORT + values for the ALLOCATION_LENGTH. Give it what it wants +- if we get an Sense Key of 05 Illegal Request with a ++ if we get an Sense Key of 05 Illegal Request with a + CDB position of 7 as the field in error. + */ + +@@ -882,7 +883,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, + { + /* TransportElementDescriptor = + (TransportElementDescriptor_T *) DataPointer; */ +- memcpy(&TEBuf, DataPointer, ++ memcpy(&TEBuf, DataPointer, + (TransportElementDescriptorLength <= sizeof(TEBuf)) ? + TransportElementDescriptorLength : + sizeof(TEBuf)); +@@ -909,7 +910,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, + case MediumTransportElement: + ElementStatus->TransportElementAddress = BigEndian16(TransportElementDescriptor->ElementAddress); + #ifdef DEBUG +- fprintf(stderr,"TransportElementAddress=%d\n",ElementStatus->TransportElementAddress); ++ fprintf(stderr,"TransportElementAddress=%d\n",ElementStatus->TransportElementAddress); + #endif + break; + +@@ -936,7 +937,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, + ElementStatus->StorageElementFull[ImportExportIndex] = + TransportElementDescriptor->Full; + +- if ( (TransportElementDescriptorLength > 11) && ++ if ( (TransportElementDescriptorLength > 11) && + (ElementStatusPage->VolBits & E2_AVOLTAG)) + { + copy_barcode(TransportElementDescriptor->AlternateVolumeTag, +@@ -945,8 +946,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, + else + { + ElementStatus->AlternateVolumeTag[ImportExportIndex][0] = 0; /* null string. */; +- } +- if ((TransportElementDescriptorLength > 11) && ++ } ++ if ((TransportElementDescriptorLength > 11) && + (ElementStatusPage->VolBits & E2_PVOLTAG)) + { + copy_barcode(TransportElementDescriptor->PrimaryVolumeTag, +@@ -967,8 +968,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, + fprintf(stderr,"StorageElementCount=%d ElementAddress = %d ",ElementStatus->StorageElementCount,BigEndian16(TransportElementDescriptor->ElementAddress)); + #endif + /* ATL/Exabyte kludge -- skip slots that aren't installed :-( */ +- if (TransportElementDescriptor->AdditionalSenseCode==0x83 && +- TransportElementDescriptor->AdditionalSenseCodeQualifier==0x02) ++ if (TransportElementDescriptor->AdditionalSenseCode==0x83 && ++ TransportElementDescriptor->AdditionalSenseCodeQualifier==0x02) + continue; + + ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount] = +@@ -986,7 +987,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, + ElementStatus->StorageElementCount; /* slot idx. */ + /* ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount]; */ + } +- if ((TransportElementDescriptorLength > 11) && ++ if ((TransportElementDescriptorLength > 11) && + (ElementStatusPage->VolBits & E2_AVOLTAG)) + { + copy_barcode(TransportElementDescriptor->AlternateVolumeTag, +@@ -995,8 +996,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, + else + { + ElementStatus->AlternateVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */; +- } +- if ((TransportElementDescriptorLength > 11) && ++ } ++ if ((TransportElementDescriptorLength > 11) && + (ElementStatusPage->VolBits & E2_PVOLTAG)) + { + copy_barcode(TransportElementDescriptor->PrimaryVolumeTag, +@@ -1009,9 +1010,9 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, + + ElementStatus->StorageElementCount++; + /* +- Note that the original mtx had no check here for ++ Note that the original mtx had no check here for + buffer overflow, though some drives might mistakingly +- do one... ++ do one... + */ + + if (ElementStatus->StorageElementCount > mode_sense->NumStorage) +@@ -1033,33 +1034,33 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, + report that they have a 2nd tape drive when they don't. We + could generalize this in an ideal world, but my attempt to + do so failed with dual-drive Exabyte tape libraries that +- *DID* have the second drive. Sigh. ++ *DID* have the second drive. Sigh. + */ +- if (TransportElementDescriptor->AdditionalSenseCode==0x83 && ++ if (TransportElementDescriptor->AdditionalSenseCode==0x83 && + TransportElementDescriptor->AdditionalSenseCodeQualifier==0x04) + { + continue; + } + + /* generalize it. Does it work? Let's try it! */ +- /* ++ /* + No, dammit, following does not work on dual-drive Exabyte + 'cause if a tape is in the drive, it sets the AdditionalSense + code to something (sigh). + */ + /* if (TransportElementDescriptor->AdditionalSenseCode!=0) + continue; +- */ ++ */ + + ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount] = + BigEndian16(TransportElementDescriptor->ElementAddress); +- ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount] = ++ ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount] = + TransportElementDescriptor->Full; + ElementStatus->DataTransferElementSourceStorageElementNumber[ElementStatus->DataTransferElementCount] = + BigEndian16(TransportElementDescriptor->SourceStorageElementAddress); + + #ifdef DEBUG +- fprintf(stderr, "%d: ElementAddress = %d, Full = %d, SourceElement = %d\n", ++ fprintf(stderr, "%d: ElementAddress = %d, Full = %d, SourceElement = %d\n", + ElementStatus->DataTransferElementCount, + ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount], + ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount], +@@ -1118,17 +1119,17 @@ static void ParseElementStatus( int *EmptyStorageElementAddress, + /* + * We no longer do the funky trick to figure out ALLOCATION_LENGTH. + * Instead, we use the SCSI Generic command rather than SEND_SCSI_COMMAND +- * under Linux, which gets around the @#%@ 4k buffer size in Linux. ++ * under Linux, which gets around the @#%@ 4k buffer size in Linux. + * We still have the restriction that Linux cuts off the last two + * bytes of the SENSE DATA (Q#@$%@#$^ Linux!). Which means that the +- * verbose widget won't work :-(. +- ++ * verbose widget won't work :-(. ++ + * We now look for that "attached" bit in the inquiry_info to see whether + * to use READ_ELEMENT_ATTACHED or plain old READ_ELEMENT. In addition, we + * look at the device type in the inquiry_info to see whether it is a media + * changer or tape device, and if it's a media changer device, we ignore the + * attached bit (one beta tester found an old 4-tape DAT changer that set +- * the attached bit for both the tape device AND the media changer device). ++ * the attached bit for both the tape device AND the media changer device). + + */ + +@@ -1155,7 +1156,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + + if (flags->no_attached) + { +- /* override, sigh */ ++ /* override, sigh */ + is_attached = false; + } + +@@ -1185,7 +1186,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + ElementStatus->DataTransferElementCount = 0; + + /* first, allocate some empty storage stuff: Note that we pass this +- * down to ParseElementStatus (sigh!) ++ * down to ParseElementStatus (sigh!) + */ + + EmptyStorageElementAddress = (int *)xzmalloc((mode_sense->NumStorage+1)*sizeof(int)); +@@ -1202,7 +1203,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + for (i = 0; i < mode_sense->NumDataTransfer; i++) + { + /* initialize them to an illegal # so that we can fix later... */ +- ElementStatus->DataTransferElementSourceStorageElementNumber[i] = -1; ++ ElementStatus->DataTransferElementSourceStorageElementNumber[i] = -1; + } + + if (flags->querytype == MTX_ELEMENTSTATUS_ORIGINAL) +@@ -1308,7 +1309,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + PrintRequestSense(RequestSense); + #endif + FreeElementData(ElementStatus); +- return NULL; ++ return NULL; + } + + #ifdef DEBUG +@@ -1323,7 +1324,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + + /* grr, damned brain dead HP doesn't report that it has any! */ + if (!mode_sense->NumMediumTransport) +- { ++ { + ElementStatus->TransportElementAddress = 0; /* default it sensibly :-(. */ + } + else +@@ -1347,8 +1348,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + PrintRequestSense(RequestSense); + #endif + FreeElementData(ElementStatus); +- return NULL; +- } ++ return NULL; ++ } + #ifdef DEBUG + fprintf(stderr,"Parsing robot arm data\n"); + #endif +@@ -1366,8 +1367,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + fprintf(stderr,"Using alternative element status polling method (all elements)\n"); + #endif + /* ----------------- ALL Elements ---------------------- */ +- /* Just keep asking for elements till no more are returned +- - increment our starting address as we go acording to the ++ /* Just keep asking for elements till no more are returned ++ - increment our starting address as we go acording to the + number of elements returned from the last call + */ + +@@ -1384,7 +1385,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + mode_sense->MaxReadElementStatusData); + if (!DataBuffer) + { +- if (RequestSense->AdditionalSenseCode == 0x21 && ++ if (RequestSense->AdditionalSenseCode == 0x21 && + RequestSense->AdditionalSenseCodeQualifier == 0x01) + { + /* Error is invalid element address, we've probably just hit the end */ +@@ -1393,8 +1394,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + + /* darn. Free up stuff and return. */ + FreeElementData(ElementStatus); +- return NULL; +- } ++ return NULL; ++ } + + nLastEl = nNextEl; + +@@ -1423,7 +1424,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + * + * Pass1: + * Translate from raw element # to our translated # (if possible). +- * First, check the SourceStorageElementNumbers against the list of ++ * First, check the SourceStorageElementNumbers against the list of + * filled slots. If the slots indicated are empty, we accept that list as + * valid. Otherwise decide the SourceStorageElementNumbers are invalid. + * +@@ -1432,7 +1433,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + * then we must search for free slots, and assign SourceStorageElementNumbers + * to those free slots. We happen to already built a list of free + * slots as part of the process of reading the storage element numbers +- * from the tape. So that's easy enough to do! ++ * from the tape. So that's easy enough to do! + */ + + #ifdef DEBUG_TAPELIST +@@ -1448,7 +1449,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + + /* + * Now we re-assign origin slots if the "real" origin slot +- * is obviously defective: ++ * is obviously defective: + */ + /* pass one: */ + for (i = 0; i < ElementStatus->DataTransferElementCount; i++) +@@ -1486,12 +1487,12 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T * + * drives will be assigned a -1 (see the initialization loop for + * EmptyStorageElementAddress above), which will be reported as "slot 0" + * by the user interface. This is an invalid value, but more useful for us +- * to have than just crapping out here :-(. ++ * to have than just crapping out here :-(. + */ + empty_idx=0; + for (i = 0; i < ElementStatus->DataTransferElementCount; i++) + { +- if (ElementStatus->DataTransferElementFull[i] && ++ if (ElementStatus->DataTransferElementFull[i] && + ElementStatus->DataTransferElementSourceStorageElementNumber[i] < 0) + { + #ifdef DEBUG_TAPELIST +@@ -1543,7 +1544,7 @@ RequestSense_T *PositionElement(DEVICE_TYPE MediumChangerFD, + + /* Now the actual media movement routine! */ + RequestSense_T *MoveMedium( DEVICE_TYPE MediumChangerFD, int SourceAddress, +- int DestinationAddress, ++ int DestinationAddress, + ElementStatus_T *ElementStatus, + Inquiry_T *inquiry_info, SCSI_Flags_T *flags) + { +@@ -1646,7 +1647,7 @@ RequestSense_T *ExchangeMedium( DEVICE_TYPE MediumChangerFD, int SourceAddress, + + #ifdef DEBUG_EXCHANGE + dump_cdb(&CDB,12); +-#endif ++#endif + + if (SCSI_ExecuteCommand(MediumChangerFD, Output, &CDB, 12, + NULL, 0, RequestSense) != 0) +@@ -1690,8 +1691,8 @@ RequestSense_T *Erase(DEVICE_TYPE MediumChangerFD) + return NULL; /* Success! */ + } + +-/* Routine to send an LOAD/UNLOAD from the MMC/SSC spec to a device. +- * For tapes and changers this can be used either to eject a tape ++/* Routine to send an LOAD/UNLOAD from the MMC/SSC spec to a device. ++ * For tapes and changers this can be used either to eject a tape + * or to eject a magazine (on some Seagate changers, when sent to LUN 1 ). + * For CD/DVDs this is used to Load or Unload a disc which is required by + * some media changers. +@@ -1721,8 +1722,8 @@ int LoadUnload(DEVICE_TYPE fd, int bLoad) + return 0; /* did do! */ + } + +-/* Routine to send an START/STOP from the MMC/SSC spec to a device. +- * For tape drives this may be required prior to using the changer ++/* Routine to send an START/STOP from the MMC/SSC spec to a device. ++ * For tape drives this may be required prior to using the changer + * Load or Unload commands. + * For CD/DVD drives this is used to Load or Unload a disc which may be + * required by some media changers. +@@ -1746,9 +1747,9 @@ int StartStop(DEVICE_TYPE fd, int bStart) + return 0; /* did do! */ + } + +-/* Routine to send a LOCK/UNLOCK from the SSC/MMC spec to a device. ++/* Routine to send a LOCK/UNLOCK from the SSC/MMC spec to a device. + * This can be used to prevent or allow the Tape or CD/DVD from being +- * removed. ++ * removed. + */ + + int LockUnlock(DEVICE_TYPE fd, int bLock) +@@ -1876,7 +1877,7 @@ void PrintRequestSense(RequestSense_T *RequestSense) + fprintf(stderr, "mtx: Request Sense: Valid Residual=%s\n", RequestSense->Valid ? Yes : No); + + if (RequestSense->ErrorCode == 0x70) +- { ++ { + msg = "Current" ; + } + else if (RequestSense->ErrorCode == 0x71)