Imported Upstream version 2.5.1p1
[debian/amanda] / changer-src / scsi-linux.c
index 6557fbc68f72090fbe260354e0e412b377a25c38..9885349fb52161ad4b355974bcbd19b92cf9d584 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: scsi-linux.c,v 1.1.2.18.4.1.2.5 2003/07/05 16:59:01 ant Exp $
+ * $Id: scsi-linux.c,v 1.30 2006/07/06 11:57:28 martinea Exp $
  *
  * Interface to execute SCSI commands on Linux
  *
 
 #include <scsi-defs.h>
 
+extern OpenFiles_T *pDev;
 
-void SCSI_OS_Version()
+void SCSI_OS_Version(void)
 {
 #ifndef lint
-   static char rcsid[] = "$Id: scsi-linux.c,v 1.1.2.18.4.1.2.5 2003/07/05 16:59:01 ant Exp $";
+   static char rcsid[] = "$Id: scsi-linux.c,v 1.30 2006/07/06 11:57:28 martinea Exp $";
    DebugPrint(DEBUG_ERROR, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
 #endif
 }
 
 int SCSI_CloseDevice(int DeviceFD)
 {
-  extern OpenFiles_T *pDev;
   int ret = 0;
   
   if (pDev[DeviceFD].devopen == 1)
@@ -114,12 +114,9 @@ int SCSI_CloseDevice(int DeviceFD)
 #ifdef LINUX_SG
 int SCSI_OpenDevice(int ip)
 {
-  extern OpenFiles_T *pDev;
   int DeviceFD;
   int i;
   int timeout;
-  int sg_info = 0;                /* Used to get some infos about the sg interface */
-  int ret = 0;                    /* To store return results from ioctl etc */
   struct stat pstat;
   char *buffer = NULL ;           /* Will contain the device name after checking */
   int openmode = O_RDONLY;
@@ -136,12 +133,12 @@ int SCSI_OpenDevice(int ip)
               if (S_ISLNK(pstat.st_mode) == 1)
                 {
                   DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : is a link, checking destination\n");
-                  if ((buffer = (char *)malloc(512)) == NULL)
+                  if ((buffer = (char *)malloc(513)) == NULL)
                     {
                       DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_OpenDevice : malloc failed\n");
                       return(0);
                     }
-                  memset(buffer, 0, 512);
+                  memset(buffer, 0, 513);
                   if (( i = readlink(pDev[ip].dev, buffer, 512)) == -1)
                     {
                       if (errno == ENAMETOOLONG )
@@ -177,13 +174,14 @@ int SCSI_OpenDevice(int ip)
         }
       
       DebugPrint(DEBUG_INFO, SECTION_SCSI,"Try to open %s\n", buffer);
-      if ((DeviceFD = open(buffer, openmode)) > 0)
+      if ((DeviceFD = open(buffer, openmode)) >= 0)
         {
           pDev[ip].avail = 1;
           pDev[ip].devopen = 1;
           pDev[ip].fd = DeviceFD;
         } else {
           DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice open failed\n");
+         amfree(buffer);
           return(0);
         }
       
@@ -193,23 +191,9 @@ int SCSI_OpenDevice(int ip)
           pDev[ip].SCSI = 1;
         }
       
-      pDev[ip].dev = stralloc(buffer);
+      pDev[ip].dev = buffer;
       if (pDev[ip].SCSI == 1)
         {
-          if ((ret = ioctl(DeviceFD, SG_GET_VERSION_NUM, &sg_info)) == 0)
-            {
-              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_VERSION %d\n",sg_info);  
-            } else {
-              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_VERSION ioctl returned %d\n", ret);
-            }
-
-          if ((ret = ioctl(DeviceFD, SG_GET_RESERVED_SIZE, &sg_info)) == 0)
-            {
-              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_RESERVED_SIZE %d\n",sg_info);  
-            } else {
-              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_RESERVED_SIZE ioctl returned %d\n", ret);
-            }
-
           DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : use SG interface\n");
           if ((timeout = ioctl(pDev[ip].fd, SG_GET_TIMEOUT)) > 0) 
             {
@@ -221,7 +205,7 @@ int SCSI_OpenDevice(int ip)
                 }
             }
           pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
-          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+          if (SCSI_Inquiry(ip, pDev[ip].inquiry, (u_char)INQUIRY_SIZE) == 0)
             {
               if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
                 {
@@ -248,7 +232,7 @@ int SCSI_OpenDevice(int ip)
                   return(1);
                 } else {
                   close(DeviceFD);
-                  free(pDev[ip].inquiry);
+                  amfree(pDev[ip].inquiry);
                   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice (0)\n");
                   return(0);
                 }
@@ -256,7 +240,7 @@ int SCSI_OpenDevice(int ip)
               pDev[ip].SCSI = 0;
               pDev[ip].devopen = 0;
               close(DeviceFD);
-              free(pDev[ip].inquiry);
+              amfree(pDev[ip].inquiry);
               pDev[ip].inquiry = NULL;
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice (1)\n");
               return(1);
@@ -276,7 +260,7 @@ int SCSI_OpenDevice(int ip)
         } else {
           openmode = O_RDONLY;
         }
-      if ((DeviceFD = open(pDev[ip].dev, openmode)) > 0)
+      if ((DeviceFD = open(pDev[ip].dev, openmode)) >= 0)
         {
           pDev[ip].devopen = 1;
           pDev[ip].fd = DeviceFD;
@@ -303,21 +287,27 @@ int SCSI_OpenDevice(int ip)
   return(0);
 }
 
-#define SCSI_OFF sizeof(struct sg_header)
+#define SCSI_OFF SIZEOF(struct sg_header)
 int SCSI_ExecuteCommand(int DeviceFD,
                         Direction_T Direction,
                         CDB_T CDB,
-                        int CDB_Length,
+                        size_t CDB_Length,
                         void *DataBuffer,
-                        int DataBufferLength,
-                        char *pRequestSense,
-                        int RequestSenseLength)
+                        size_t DataBufferLength,
+                        RequestSense_T *pRequestSense,
+                        size_t RequestSenseLength)
 {
-  extern OpenFiles_T *pDev;
   struct sg_header *psg_header;
   char *buffer;
-  int osize = 0;
-  int status;
+  size_t osize = 0;
+  ssize_t status;
+
+  /* Basic sanity checks */
+  assert(CDB_Length <= UCHAR_MAX);
+  assert(RequestSenseLength <= UCHAR_MAX);
+
+  /* Clear buffer for cases where sense is not returned */
+  memset(pRequestSense, 0, RequestSenseLength);
 
   if (pDev[DeviceFD].avail == 0)
     {
@@ -325,18 +315,22 @@ int SCSI_ExecuteCommand(int DeviceFD,
     }
 
   if (pDev[DeviceFD].devopen == 0)
+      if (SCSI_OpenDevice(DeviceFD) == 0)
+          return(-1);
+  
+  if (SCSI_OFF + CDB_Length + DataBufferLength > 4096) 
     {
-      SCSI_OpenDevice(DeviceFD);
+      SCSI_CloseDevice(DeviceFD);
+      return(-1);
     }
-  
-/*   if (SCSI_OFF + CDB_Length + DataBufferLength > 4096)  */
-/*     { */
-/*       SCSI_CloseDevice(DeviceFD); */
-/*       DebugPrint(DEBUG_ERROR, SECTION_SCSI,"##### SCSI_ExecuteCommand error, SCSI_OFF + CDB_Length + DataBufferLength > 4096\n"); */
-/*       return(-1); */
-/*     } */
 
   buffer = (char *)malloc(SCSI_OFF + CDB_Length + DataBufferLength);
+  if (buffer == NULL)
+    {
+      dbprintf(("SCSI_ExecuteCommand memory allocation failure.\n"));
+      SCSI_CloseDevice(DeviceFD);
+      return(-1);
+    }
   memset(buffer, 0, SCSI_OFF + CDB_Length + DataBufferLength);
   memcpy(buffer + SCSI_OFF, CDB, CDB_Length);
   
@@ -348,7 +342,7 @@ int SCSI_ExecuteCommand(int DeviceFD,
       psg_header->twelve_byte = 0;
     }
   psg_header->result = 0;
-  psg_header->reply_len = SCSI_OFF + DataBufferLength;
+  psg_header->reply_len = (int)(SCSI_OFF + DataBufferLength);
   
   switch (Direction)
     {
@@ -363,11 +357,13 @@ int SCSI_ExecuteCommand(int DeviceFD,
   DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
   
   status = write(pDev[DeviceFD].fd, buffer, SCSI_OFF + CDB_Length + osize);
-  if ( status < 0 || status != SCSI_OFF + CDB_Length + osize ||
-       psg_header->result ) 
+  if ( (status < (ssize_t)0) ||
+       (status != (ssize_t)(SCSI_OFF + CDB_Length + osize)) ||
+       (psg_header->result != 0)) 
     {
       dbprintf(("SCSI_ExecuteCommand error send \n"));
       SCSI_CloseDevice(DeviceFD);
+      amfree(buffer);
       return(SCSI_ERROR);
     }
   
@@ -376,12 +372,14 @@ int SCSI_ExecuteCommand(int DeviceFD,
   memset(pRequestSense, 0, RequestSenseLength);
   memcpy(pRequestSense, psg_header->sense_buffer, 16);
   
-  if ( status < 0 || status != SCSI_OFF + DataBufferLength || 
-       psg_header->result ) 
+  if ( (status < 0) ||
+       (status != (ssize_t)(SCSI_OFF + DataBufferLength)) || 
+       (psg_header->result != 0)) 
     { 
       dbprintf(("SCSI_ExecuteCommand error read \n"));
-      dbprintf(("Status %d (%d) %2X\n", status, SCSI_OFF + DataBufferLength, psg_header->result ));
+      dbprintf(("Status %d (%d) %2X\n", status, SCSI_OFF + DataBufferLength,psg_header->result ));
       SCSI_CloseDevice(DeviceFD);
+      amfree(buffer);
       return(SCSI_ERROR);
     }
 
@@ -390,8 +388,8 @@ int SCSI_ExecuteCommand(int DeviceFD,
        memcpy(DataBuffer, buffer + SCSI_OFF, DataBufferLength);
     }
 
-  free(buffer);
   SCSI_CloseDevice(DeviceFD);
+  amfree(buffer);
   return(SCSI_OK);
 }
 
@@ -410,21 +408,20 @@ static inline int max(int x, int y)
 
 int SCSI_OpenDevice(int ip)
 {
-  extern OpenFiles_T *pDev;
   int DeviceFD;
   int i;
 
   if (pDev[ip].inqdone == 0)
     {
       pDev[ip].inqdone = 1;
-      if ((DeviceFD = open(pDev[ip].dev, O_RDWR)) > 0)
+      if ((DeviceFD = open(pDev[ip].dev, O_RDWR)) >= 0)
         {
           pDev[ip].avail = 1;
           pDev[ip].fd = DeviceFD;
           pDev[ip].SCSI = 0;
           pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
           dbprintf(("SCSI_OpenDevice : use ioctl interface\n"));
-          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+          if (SCSI_Inquiry(ip, pDev[ip].inquiry, (u_char)INQUIRY_SIZE) == 0)
             {
               if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
                 {
@@ -435,20 +432,20 @@ int SCSI_OpenDevice(int ip)
                   PrintInquiry(pDev[ip].inquiry);
                   return(1);
                 } else {
-                  free(pDev[ip].inquiry);
+                  amfree(pDev[ip].inquiry);
                   close(DeviceFD);
                   return(0);
                 }
             } else {
               close(DeviceFD);
-              free(pDev[ip].inquiry);
+              amfree(pDev[ip].inquiry);
               pDev[ip].inquiry = NULL;
               return(1);
             }
         }
       return(1); 
     } else {
-      if ((DeviceFD = open(pDev[ip].dev, O_RDWR)) > 0)
+      if ((DeviceFD = open(pDev[ip].dev, O_RDWR)) >= 0)
         {
           pDev[ip].fd = DeviceFD;
           pDev[ip].devopen = 1;
@@ -466,10 +463,9 @@ int SCSI_ExecuteCommand(int DeviceFD,
                         int CDB_Length,
                         void *DataBuffer,
                         int DataBufferLength,
-                        char *pRequestSense,
+                        RequestSense_T *pRequestSense,
                         int RequestSenseLength)
 {
-  extern OpenFiles_T *pDev;
   unsigned char *Command;
   int Zero = 0, Result;
  
@@ -480,7 +476,8 @@ int SCSI_ExecuteCommand(int DeviceFD,
 
   if (pDev[DeviceFD].devopen == 0)
     {
-      SCSI_OpenDevice(DeviceFD);
+      if (SCSI_OpenDevice(DeviceFD) == 0)
+          return(-1);
     }
 
   memset(pRequestSense, 0, RequestSenseLength);
@@ -510,7 +507,7 @@ int SCSI_ExecuteCommand(int DeviceFD,
     memcpy(pRequestSense, &Command[8], RequestSenseLength);
   else if (Direction == Input)
     memcpy(DataBuffer, &Command[8], DataBufferLength);
-  free(Command);
+  amfree(Command);
   SCSI_CloseDevice(DeviceFD);
 
   switch(Result)
@@ -531,13 +528,13 @@ int SCSI_ExecuteCommand(int DeviceFD,
  */
 int Tape_Ioctl( int DeviceFD, int command)
 {
-  extern OpenFiles_T *pDev;
   struct mtop mtop;
   int ret = 0;
 
   if (pDev[DeviceFD].devopen == 0)
     {
-      SCSI_OpenDevice(DeviceFD);
+      if (SCSI_OpenDevice(DeviceFD) == 0)
+          return(-1);
     }
 
   switch (command)
@@ -552,7 +549,7 @@ int Tape_Ioctl( int DeviceFD, int command)
 
   if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
     {
-      dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+      dbprintf(("Tape_Ioctl error ioctl %s\n",strerror(errno)));
       SCSI_CloseDevice(DeviceFD);
       return(-1);
     }
@@ -563,18 +560,20 @@ int Tape_Ioctl( int DeviceFD, int command)
 
 int Tape_Status( int DeviceFD)
 {
-  extern OpenFiles_T *pDev;
   struct mtget mtget;
   int ret = 0;
 
+  memset(&mtget, 0, SIZEOF(mtget));
   if (pDev[DeviceFD].devopen == 0)
     {
-      SCSI_OpenDevice(DeviceFD);
+      if (SCSI_OpenDevice(DeviceFD) == 0)
+          return(-1);
     }
 
   if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
   {
-     DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Tape_Status error ioctl %d\n",errno);
+     DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Tape_Status error ioctl %s\n",
+               strerror(errno));
      SCSI_CloseDevice(DeviceFD);
      return(-1);
   }
@@ -618,11 +617,13 @@ int ScanBus(int print)
 {
   DIR *dir;
   struct dirent *dirent;
-  extern OpenFiles_T *pDev;
-  extern int errno;
   int count = 0;
 
-  dir = opendir("/dev/");
+  if ((dir = opendir("/dev/")) == NULL)
+    {
+      dbprintf(("/dev/ error: %s", strerror(errno)));
+      return 0;
+    }
 
   while ((dirent = readdir(dir)) != NULL)
     {
@@ -630,7 +631,8 @@ int ScanBus(int print)
       {
         pDev[count].dev = malloc(10);
         pDev[count].inqdone = 0;
-        sprintf(pDev[count].dev,"/dev/%s", dirent->d_name);
+        snprintf(pDev[count].dev, SIZEOF(pDev[count].dev),
+           "/dev/%s", dirent->d_name);
         if (OpenDevice(count,pDev[count].dev, "Scan", NULL ))
           {
             SCSI_CloseDevice(count);
@@ -681,7 +683,7 @@ int ScanBus(int print)
             count++;
            printf("Count %d\n",count);
           } else {
-            free(pDev[count].dev);
+            amfree(pDev[count].dev);
             pDev[count].dev=NULL;
           }
       }