home *** CD-ROM | disk | FTP | other *** search
/ M.u.C.S. Disc 2000 / MUCS2000.iso / anwend / gemar306 / plugin / source / reqsense.c < prev    next >
C/C++ Source or Header  |  1997-01-21  |  8KB  |  302 lines

  1. /*{{{}}}*/
  2. /****************************************************************************
  3.  *
  4.  *    Beschreibung  : Dies ist ein Beispiel für die Programmierung von
  5.  *                    PlugIns für GEMAR.
  6.  *                    Wenn ein Fehler bei einem SCSI-Aufruf auftritt, der
  7.  *                    Check Condition meldet, holt GEMAR die Request
  8.  *                    Sense Daten vom Gerät, um die Fehlermeldung
  9.  *                    zusammenzustellen.
  10.  *                    Falls ein PlugIn mit dem Namen REQSENSE.PLG
  11.  *                    existiert, wird dieses geladen und mit einem
  12.  *                    Zeiger auf die Request-Sense Daten aufgerufen.
  13.  *                    Das PlugIn kann dann eine differenzierte Fehlermel-
  14.  *                    dung zusammenstellen und eine Zeiger darauf
  15.  *                    liefern.
  16.  *
  17.  * $Source: /dev/e/hm2/user/gemar/plugin\RCS\REQSENSE.C,v $
  18.  *
  19.  * $Revision: 1.2 $
  20.  *
  21.  * $Author: S_Engel $
  22.  *
  23.  * $Date: 1995/10/21 17:09:14 $
  24.  *
  25.  * $State: Exp $
  26.  *
  27.  *****************************************************************************
  28.  * History:
  29.  *
  30.  * $Log: REQSENSE.C,v $
  31.  * Revision 1.2  1995/10/21  17:09:14  S_Engel
  32.  * Bugfix: Auswertung der Fehlerbits in Sensekey falsch.
  33.  *
  34.  * Revision 1.1  1995/01/01  20:03:26  S_Engel
  35.  * Initial revision
  36.  *
  37.  *
  38.  *
  39.  ****************************************************************************/
  40.  
  41.  
  42.  
  43. /* die üblichen Header-Dateien --------------- */
  44. int errno;
  45. long _FilSysV;
  46.  
  47. #include <portab.h>
  48. #include <tos.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #include <stdio.h>
  52.  
  53. char Msg[100];
  54.  
  55. typedef struct head
  56. {
  57.   int valid     : 1; 
  58.   int ErrorCode : 7;
  59. } HEADBITS;
  60.  
  61. typedef struct key
  62. {
  63.   int FM       : 1;
  64.   int EOM      : 1;
  65.   int ILI      : 1;
  66.   int reserved : 1;
  67.   Key          : 4;
  68. } KEY;
  69.  
  70. typedef struct reqsense
  71. {
  72.   char HeadBits;    /* eigentlich HEADBITS, aber Bitfield mindestens 16 Bit */
  73.   char SegmentNo;
  74.   char SenseKey;    /* eigentlich KEY, aber... */
  75.   char InfoByte1;
  76.   char InfoByte2;
  77.   char InfoByte3;
  78.   char InfoByte4;
  79.   char AddLength;
  80.   unsigned long  CmdSpecific;
  81.   char AS;
  82.   char ASQ;
  83. } REQSENSE;
  84.  
  85.  
  86. typedef struct tcall
  87. {
  88.   int   num;
  89.   long  Call;
  90. } TCALL;
  91.  
  92.  
  93. char NoSense[]          = "Kein Fehler?";
  94. char ReqSenseError[]    = "Fehler bei Request Sense!";
  95. char UnknownError[]     = "Unbekannter Fehler";
  96. char FileMark[]         = "Filemark";
  97. char EndOfMedia[]       = "Bandende";
  98. char IllegalLength[]    = "IllegalLength";
  99. char RecoveredError[]   = "Korrigierter Lesefehler";
  100. char NotReady[]         = "Nicht bereit";
  101. char MediumError[]      = "Medium-Fehler";
  102. char HardwareError[]    = "Hardware-Fehler";
  103. char IllegalRequest[]   = "Illegaler Befehl";
  104. char UnitAttention[]    = "Unit Attention";
  105. char DataProtect[]      = "Schreibschutz";
  106. char BlankCheck[]       = "Keine Daten auf dem Band";
  107. char CopyAborted[]      = "Abbruch von 'Copy'";
  108. char AbortedCommand[]   = "Abgebrocheneds Kommando";
  109. char Equal[]            = "Equal";
  110. char VolumeOverflow[]   = "Volume Overflow/Bandende";
  111. char Miscompare[]       = "Miscompare";
  112.  
  113.  
  114.  
  115. /* vom Programm übergebene Parameter */
  116. typedef struct
  117.   {
  118.     int Version;    
  119.     void *private;
  120.     int ApplId;
  121.     int VDIHandle;
  122.     char *PlugPath;
  123.     int (*Alert) (int defbutt, char *msg);
  124.   } PLUGPARMS;
  125.  
  126.  
  127. PLUGPARMS *PlugParms;
  128.  
  129. /* Rücggabestruktur */
  130. TCALL CallTab;
  131.  
  132. /* Funktionen -------------------------------- */
  133.  
  134. long cdecl CallProc (REQSENSE *SenseData);
  135.  
  136.  
  137. /***********************************************/
  138. /* Initialisierung des Moduls:                 */
  139. /***********************************************/
  140. long cdecl init(PLUGPARMS *parms)
  141. {{{
  142.   if (((long)parms == 0)             /* Keine Parameter? -> Urks     */
  143.      || (parms->Version < 0x0000))   /* Minimalversion der Parameter */
  144.   {
  145.     return 0;
  146.   }
  147.  
  148.   /* Parameterzeiger merken */
  149.   PlugParms = parms;
  150.  
  151.   CallTab.num = 1;
  152.   CallTab.Call = (long)CallProc;
  153.   
  154.   /* Adresse der Aufrufstruktur zurückgeben */
  155.   return((long)&CallTab);
  156. }}}
  157.  
  158.  
  159. /***********************************************/
  160. /* Text für AS und ASQ aus REQSENSE.DAT lesen  */
  161. /***********************************************/
  162. void GetAS(char buffer[], int AS, int ASQ)
  163. {{{
  164.   
  165.   char fname[512], msg[120];
  166.   int count, as, asq; 
  167.   FILE *file;
  168.  
  169.   /* Kopie des Pfades */
  170.   strcpy(fname, PlugParms->PlugPath);
  171.   
  172.   /* Pfad abtrennen */
  173.   for (count = (int) strlen(fname); 
  174.        (count >= 0) && (fname[count] != 92);
  175.         --count)
  176.     {
  177.       fname[count] = 0;  
  178.     }
  179.  
  180.   strcat(fname, "REQSENSE.DAT");
  181.   file = fopen(fname, "r"); 
  182.  
  183.   if (file == NULL)
  184.     {
  185.       strcpy(buffer, "REQSENSE.PLG: ");
  186.       strcat(buffer, fname);
  187.       strcat(buffer, " not found");
  188.       return;
  189.     }
  190.  
  191.   while (1)
  192.   {
  193.     if (fscanf(file, "%x %x %[#-z ]", &as, &asq, msg) == 0) 
  194.       {
  195.         /* Ende der Datei -> AS und ASQ an bereits existierende Meldung anhängen */
  196.         sprintf(msg, ": AS: $%02x, ASQ: $%02x", AS, ASQ);
  197.         strcat (buffer, msg);
  198.         break;
  199.       }
  200.     if ((AS == as) && ((ASQ == asq) || (asq == 0xFF)))
  201.     {
  202.       strcpy(buffer, msg);
  203.  
  204.       /* qualifier mit FF soll in Text einkopiert werden */
  205.       if (asq == 0xFF)
  206.         {
  207.           sprintf(buffer, msg, ASQ);
  208.         }
  209.       break;        
  210.     }
  211.   }
  212.   fclose(file);   /* Datei schlie₧en */
  213. }}}   /* GetAS */
  214.  
  215.  
  216. /***********************************************/
  217. /* die eigentliche Plug-Prozedur               */
  218. /***********************************************/
  219. long cdecl CallProc(REQSENSE *SenseData)
  220. {{{
  221.   if ((long) SenseData != -1)      /* beim Deinit-Call nichts machen */
  222.     {
  223.       if ((((int) SenseData->HeadBits & 0x7f) != 0x70)
  224.            && (((int) SenseData->HeadBits & 0x7f) != 0x71))
  225.       {
  226.         strcpy (Msg, "Was'n das'n?");
  227.       }
  228.       else
  229.       {
  230.         switch (SenseData->SenseKey & 0x0F)
  231.         {
  232. /* Es kann sein, da₧ der SenseKey 0 ist, aber in den beren Bits etwas markiert ist.
  233.           case 0x00: strcpy(Msg, NoSense); 
  234.                      break;
  235.  */ 
  236.           case 0x01: strcpy(Msg, RecoveredError);
  237.                      break;
  238.           case 0x02: strcpy(Msg, NotReady);
  239.                      break;
  240.           case 0x03: strcpy(Msg, MediumError);
  241.                      break;
  242.           case 0x04: strcpy(Msg, HardwareError);
  243.                      break;
  244.           case 0x05: strcpy(Msg, IllegalRequest);
  245.                      break;
  246.           case 0x06: strcpy(Msg, UnitAttention);
  247.                      break;
  248.           case 0x07: strcpy(Msg, DataProtect);
  249.                      break;
  250.           case 0x08: strcpy(Msg, BlankCheck);
  251.                      break;
  252.       /* |09H : RETURN VendorUnique; */
  253.           case 0x0A: strcpy(Msg, CopyAborted);
  254.                      break;
  255.           case 0x0B: strcpy(Msg, AbortedCommand);
  256.                      break;
  257.           case 0x0C: strcpy(Msg, Equal);
  258.                      break;
  259.           case 0x0D: strcpy(Msg, VolumeOverflow);
  260.                      break;
  261.           case 0x0E: strcpy(Msg, Miscompare);
  262.                      break;
  263.           
  264.           default:   if (SenseData->SenseKey & 0x80)
  265.                      {
  266.                        strcpy(Msg, FileMark);
  267.                      } 
  268.                      else
  269.                      {
  270.                        if (SenseData->SenseKey & 0x40)
  271.                        {
  272.                          strcpy(Msg, EndOfMedia);
  273.                        }
  274.                        else
  275.                        {
  276.                          if (SenseData->SenseKey & 0x20)
  277.                          {
  278.                            strcpy(Msg, IllegalLength);
  279.                          }
  280.                          else
  281.                          {
  282.                            sprintf(Msg, " Code : $%x Key : $%x", 
  283.                                    SenseData->HeadBits, SenseData->SenseKey);
  284.                          }
  285.                        }
  286.                      }
  287.         }
  288.       }
  289.       
  290.       /* und den Additional Sense-Code, wenn er gemeldet ist */
  291.       if (SenseData->AS != 0)
  292.       {
  293.         GetAS(Msg, SenseData->AS, SenseData->ASQ);
  294.       }
  295.        return (long)&Msg;
  296.     }
  297.   else
  298.     {
  299.       return 0;
  300.     }
  301. }}}     /* CallProc */
  302.