--- CHANGES.;-0	Tue Jan 20 16:16:22 1998
+++ CHANGES	Tue Aug 21 00:30:24 2001
@@ -46,4 +46,11 @@
 
 1.04  Tue Jan 20 16:20:05 1998
     - Added the (undocumented) POWER_VECTOR, FAN_VECTOR, TEMPERATURE_VECTOR
-      and THERMAL_VECTOR items, along with a handle_strange function.
\ No newline at end of file
+      and THERMAL_VECTOR items, along with a handle_strange function.
+
+1.05  Mon Aug 20 19:09:00 2001
+    - Added an (undocumented) fix to the environment handler checks to keep them
+      from breaking get_all_sys_info_items when the cpu routines don't support
+      them -- otherwise you get %SYSTEM-E-NOT_LOADED.
+    - miscellaneous fixes and cleanups -- no longer need to build with POLLUTE=1
+
--- System.pm;-0	Wed Jan 21 10:05:22 1998
+++ System.pm	Tue Aug 21 00:29:49 2001
@@ -14,7 +14,7 @@
 @EXPORT_OK = qw(&sys_info_names        &get_all_sys_info_items
                 &get_one_sys_info_item &decode_sys_info_bitmap
                 &node_list);
-$VERSION = '1.04';
+$VERSION = '1.05';
 
 bootstrap VMS::System $VERSION;
 
--- System.xs;-0	Wed Jan 21 09:58:04 1998
+++ System.xs	Tue Aug 21 00:29:44 2001
@@ -59,9 +59,9 @@
 #define bit_test(HVPointer, BitToCheck, HVEntryName, EncodedMask) \
 { \
     if ((EncodedMask) & (BitToCheck)) \
-    hv_store((HVPointer), (HVEntryName), strlen((HVEntryName)), &sv_yes, 0); \
+    hv_store((HVPointer), (HVEntryName), strlen((HVEntryName)), &PL_sv_yes, 0); \
     else \
-    hv_store((HVPointer), (HVEntryName), strlen((HVEntryName)), &sv_no, 0);}   
+    hv_store((HVPointer), (HVEntryName), strlen((HVEntryName)), &PL_sv_no, 0);}   
 
 #define IS_STRING 1
 #define IS_LONGWORD 2
@@ -114,7 +114,7 @@
   {"CLUSTER_VOTES", SYI$_CLUSTER_VOTES, 2, IS_WORD, FALSE},
   {"CONTIG_GBLPAGES", SYI$_CONTIG_GBLPAGES, 4, IS_LONGWORD, FALSE},
   {"CPU", SYI$_CPU, 4, IS_ENUM, TRUE},
-#ifdef SYI$_CPU_TYPE
+#ifdef SYI$_CPUTYPE
   {"CPUTYPE", SYI$_CPUTYPE, 4, IS_ENUM, FALSE},
 #endif
   {"DECIMAL_EMULATED", SYI$_DECIMAL_EMULATED, 1, IS_BYTEBOOL, TRUE},
@@ -796,7 +796,7 @@
   {"TBSKIPWSL", SYI$_TBSKIPWSL, 4, IS_LONGWORD, TRUE},
   {"TIME_CONTROL", SYI$_TIME_CONTROL, 4, IS_LONGWORD, TRUE},
 #ifdef SYI$_VBN_CACHE_S
-  {"VBN_CACHE_S", SYI$_VBS_CACHE_S, 4, IS_LONGWORD, TRUE},
+  {"VBN_CACHE_S", SYI$_VBN_CACHE_S, 4, IS_LONGWORD, TRUE},
 #endif
 #ifdef SYI$_VBSS_ENABLE
   {"VBSS_ENABLE", SYI$_VBSS_ENABLE, 4, IS_LONGWORD, TRUE},
@@ -824,27 +824,25 @@
   {"WPRE_SIZE", SYI$_WPRE_SIZE, 4, IS_LONGWORD, TRUE},
   {"WPTTE_SIZE", SYI$_WPTTE_SIZE, 4, IS_LONGWORD, TRUE},
   {"WRITABLESYS", SYI$_WRITABLESYS, 4, IS_LONGWORD, TRUE},
-  {"WRITESYSPARAMS", SYI$_WRITESYSPARAMS, 4, IS_LONGWORD, TRUE},
+  {"WRITESYSPARAMS", SYI$_WRITESYSPARAMS, 4, IS_LONGWORD, TRUE}
 #ifdef SYI$_XQPCTL2
-  {"XQPCTL2", SYI$_XQPCTL2, 4, IS_LONGWORD, TRUE},
+  ,{"XQPCTL2", SYI$_XQPCTL2, 4, IS_LONGWORD, TRUE}
 #endif
 #ifdef SYI$_XQPCTLD1
-  {"XQPCTLD1", SYI$_XQPCTLD1, 4, IS_LONGWORD, TRUE},
+  ,{"XQPCTLD1", SYI$_XQPCTLD1, 4, IS_LONGWORD, TRUE}
 #endif
-#ifdef SYI$_POWER_VECTOR
+};
+
+/* The Environmental Event Machine Check Handler list */
+#if __VMS_VER >= 70200000  /****  Supported starting with OpenVMS V7.2  ****/
+struct SysInfoID SysInfoEEMCHList[] =
+{
   {"POWER_VECTOR", SYI$_POWER_VECTOR, 16, IS_STRANGE, TRUE},
-#endif
-#ifdef SYI$_FAN_VECTOR
   {"FAN_VECTOR", SYI$_FAN_VECTOR, 16, IS_STRANGE, TRUE},
-#endif
-#ifdef SYI$_TEMPERATURE_VECTOR
   {"TEMPERATURE_VECTOR", SYI$_TEMPERATURE_VECTOR, 16, IS_STRANGE, TRUE},
-#endif
-#ifdef SYI$_THERMAL_VECTOR
-  {"THERMAL_VECTOR", SYI$_THERMAL_VECTOR, 16, IS_STRANGE, TRUE},
-#endif
-  {NULL, 0, 0, 0, 0}
+  {"THERMAL_VECTOR", SYI$_THERMAL_VECTOR, 16, IS_STRANGE, TRUE}
 };
+#endif
 
 char *MonthNames[12] = {
   "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
@@ -853,11 +851,15 @@
 /* Globals to track how many different pieces of info we can return, as */
 /* well as how much space we'd need to grab to store it. */
 static int SysInfoCount = 0;
+static int SysInfoEEMCHCount = 0;
 static int SysInfoMallocSize = 0;
 static char LocalNodeName[255] = {""};
 static short LocalNodeNameLen;
 static long LocalNodeCSID;
 static short LocalNodeCSIDLen;
+static long LocalNodeCRD;
+static short LocalNodeCRDLen;
+static char HasEEMCH = 0;
 
 void
 tote_up_info_count()
@@ -870,25 +872,47 @@
     /* Add in a couple extra, just to be safe */
     SysInfoMallocSize += 8;
   }
+
+#if __VMS_VER >= 70200000  /****  Supported starting with OpenVMS V7.2  ****/
+  if (!HasEEMCH) return;
+
+  for(SysInfoEEMCHCount = 0; SysInfoEEMCHList[SysInfoEEMCHCount].SysInfoName;
+      SysInfoEEMCHCount++) {
+    /* While we're here, we might as well get a generous estimate of how */
+    /* much space we'll need for all the buffers */
+    SysInfoMallocSize += SysInfoEEMCHList[SysInfoEEMCHCount].BufferLen;
+    /* Add in a couple extra, just to be safe */
+    SysInfoMallocSize += 8;
+  }
+#endif
 }    
 
-/* This routine makes a quickie call to getsyi to grab the local nodename */
-/* and csid. */
+/* This routine makes a quickie call to getsyi to grab the local nodename, */
+/* csid, and CRD_CONTROL. */
 void
 set_local_node_name()
 {
   short status;
   if (!LocalNodeName[0]) {
-    ITMLST NodeInfoFetch[3];
-    Zero(&NodeInfoFetch[0], 3, ITMLST);
+    ITMLST NodeInfoFetch[4];
+    Zero(&NodeInfoFetch[0], 4, ITMLST);
     init_itemlist(&NodeInfoFetch[0], 255, SYI$_NODENAME, LocalNodeName,
                   &LocalNodeNameLen);
-    init_itemlist(&NodeInfoFetch[1], 255, SYI$_NODENAME, &LocalNodeCSID,
+    init_itemlist(&NodeInfoFetch[1], 4, SYI$_NODE_CSID, &LocalNodeCSID,
                   &LocalNodeCSIDLen);
+    init_itemlist(&NodeInfoFetch[2], 4, SYI$_CRD_CONTROL, &LocalNodeCRD,
+                  &LocalNodeCRDLen);
     status = sys$getsyiw(NULL, NULL, NULL, &NodeInfoFetch[0], 0, NULL, 0);
     
     /* Stick in a trailing null, just to be sure */
     LocalNodeName[LocalNodeNameLen] = 0;
+
+    /* Per sys$startup:sys$smhandler_startup.com, when bit 5 of CRD_CONTROL is
+     * set, then we can do the environmental machine checks (poor choice of 
+     * terminology -- we aren't talking about machine check exceptions, just
+     * checking the processor for how it's feeling).
+     */
+   if (LocalNodeCRD & 0x20) HasEEMCH = 1;
   }
 }
 
@@ -899,6 +923,9 @@
 SV *
 decode_strange(FetchedItem *ItemToDecode)
 {
+  /* remove this if we get other types of strange things to handle here */
+  if (!HasEEMCH) return(&PL_sv_undef);
+
 #ifdef SYI$_POWER_VECTOR
   if (ItemToDecode->ReturnType == SYI$_POWER_VECTOR) {
     AV *PowerAV;
@@ -1039,7 +1066,7 @@
 
   }
 #endif
-  return(&sv_undef);
+  return(&PL_sv_undef);
 }
      
 /* This routine takes a SYI item list ID and the value that wants to be */
@@ -1091,6 +1118,21 @@
     case 2:
       sv_setpv(WorkingSV, "DECchip 21064");
       break;
+    case 4:
+      sv_setpv(WorkingSV, "DECchip 21066");
+      break;
+    case 5:
+      sv_setpv(WorkingSV, "DECchip 21164");
+      break;
+    case 6:
+      sv_setpv(WorkingSV, "DECchip 21064A");
+      break;
+    case 7:
+      sv_setpv(WorkingSV, "DECchip 21164A");
+      break;
+    case 8:
+      sv_setpv(WorkingSV, "DECchip 21264");
+      break;
     default:
       sv_setpv(WorkingSV, "Unknown CPU Type");
       break;
@@ -1201,7 +1243,7 @@
     LocalNode = FALSE;
 
   for (i = 0; SysInfoList[i].SysInfoName; i++) {
-    if (strEQ(SysInfoList[i].SysInfoName, SvPV(infoname, na))) {
+    if (strEQ(SysInfoList[i].SysInfoName, SvPV(infoname, PL_na))) {
       break;
     }
   }
@@ -1209,12 +1251,12 @@
   /* Did we find a match? If not, complain and exit */
   if (SysInfoList[i].SysInfoName == NULL) {
     warn("Invalid sys info item");
-    ST(0) = &sv_undef;
+    ST(0) = &PL_sv_undef;
   } else {
     /* Did they ask for something we can get? */
     if ((!LocalNode) && (SysInfoList[i].LocalOnly)) {
       warn("Local info for remote node requested");
-      ST(0) = &sv_undef;
+      ST(0) = &PL_sv_undef;
     } else {
       /* allocate our item list */
       ITMLST OneItem[2];
@@ -1288,7 +1330,7 @@
         
       default:
         warn("Unknown item return type");
-        ST(0) = &sv_undef;
+        ST(0) = &PL_sv_undef;
         return;
       }
       
@@ -1331,17 +1373,17 @@
           break;
         case IS_BYTEBOOL:
           if (ReturnByteBuffer)
-            ST(0) = &sv_yes;
+            ST(0) = &PL_sv_yes;
           else
-            ST(0) = &sv_no;
+            ST(0) = &PL_sv_no;
           break;
         default:
-          ST(0) = &sv_undef;
+          ST(0) = &PL_sv_undef;
           break;
         }
       } else {
         SETERRNO(EVMSERR, status);
-        ST(0) = &sv_undef;
+        ST(0) = &PL_sv_undef;
         if (status == SS$_NOSUCHNODE) {
           warn("No node of that name in the cluster");
         }
@@ -1410,12 +1452,12 @@
   }
   
   /* We need room for our item list */
-  ListOItems = malloc(sizeof(ITMLST) * (SysInfoCount + 1));
-  memset(ListOItems, 0, sizeof(ITMLST) * (SysInfoCount + 1));
-  OurDataList = malloc(sizeof(FetchedItem) * SysInfoCount);
+  ListOItems = malloc(sizeof(ITMLST) * (SysInfoCount + SysInfoEEMCHCount + 1));
+  memset(ListOItems, 0, sizeof(ITMLST) * (SysInfoCount + SysInfoEEMCHCount + 1));
+  OurDataList = malloc(sizeof(FetchedItem) * (SysInfoCount + SysInfoEEMCHCount));
   
   /* We also need room for the buffer lengths */
-  ReturnLengths = malloc(sizeof(short) * SysInfoCount);
+  ReturnLengths = malloc(sizeof(short) * (SysInfoCount + SysInfoEEMCHCount));
   
   /* Zero out the number of items we've put in the list */
   TotalItemCount = 0;
@@ -1450,6 +1492,43 @@
     TotalItemCount++;
   }
 
+  /* If we can do environmental machine checking, add those items to the list. */
+#if __VMS_VER >= 70200000  /****  Supported starting with OpenVMS V7.2  ****/
+  if (HasEEMCH) {
+   for (i = 0; i < SysInfoEEMCHCount; i++) {
+    /* Are we local? If not, skip local items */
+    if ((!LocalNode) && (SysInfoEEMCHList[i].LocalOnly))
+      continue;
+
+    /* Allocate the return data buffer and zero it. Can be oddly
+       sized, so we use the system malloc instead of New */
+    OurDataList[TotalItemCount].ReturnBuffer =
+      malloc(SysInfoEEMCHList[i].BufferLen);
+    memset(OurDataList[TotalItemCount].ReturnBuffer, 0,
+           SysInfoEEMCHList[i].BufferLen);
+        
+    /* Note some important stuff (like what we're doing) in our local */
+    /* tracking array */
+    OurDataList[TotalItemCount].ItemName = SysInfoEEMCHList[i].SysInfoName;
+    OurDataList[TotalItemCount].ReturnLength = &ReturnLengths[TotalItemCount];
+    OurDataList[TotalItemCount].ReturnType = SysInfoEEMCHList[i].ReturnType;
+    OurDataList[TotalItemCount].ItemListEntry = i;
+    
+    /* Fill in the item list */
+    init_itemlist(&ListOItems[TotalItemCount], SysInfoEEMCHList[i].BufferLen,
+                  SysInfoEEMCHList[i].SYIValue,
+                  OurDataList[TotalItemCount].ReturnBuffer,
+                  &ReturnLengths[TotalItemCount]);
+
+    /* Up the item count */
+    TotalItemCount++;
+   }
+  }
+#endif
+
+  /* Terminate the item list */
+  init_itemlist(&ListOItems[TotalItemCount], 0, 0, 0, 0);
+
   /* Make the GETSYIW call */
   status = sys$getsyiw(NULL, NULL, &NodeNameDesc, ListOItems, 0, NULL, 0);
 
@@ -1499,10 +1578,10 @@
         TempBytePointer = OurDataList[i].ReturnBuffer;
         if (*TempBytePointer)
           hv_store(AllPurposeHV, OurDataList[i].ItemName,
-                   strlen(OurDataList[i].ItemName), &sv_yes, 0);
+                   strlen(OurDataList[i].ItemName), &PL_sv_yes, 0);
         else
           hv_store(AllPurposeHV, OurDataList[i].ItemName,
-                   strlen(OurDataList[i].ItemName), &sv_no, 0);
+                   strlen(OurDataList[i].ItemName), &PL_sv_no, 0);
         break;
       #ifdef __ALPHA
       case IS_QUADWORD:
@@ -1519,7 +1598,7 @@
   } else {
     /* I think we failed */
     SETERRNO(EVMSERR, status);
-    ST(0) = &sv_undef;
+    ST(0) = &PL_sv_undef;
     
     /* An obvious failure? */
     if (status == SS$_NOSUCHNODE) {
@@ -1571,7 +1650,7 @@
   if (AllPurposeHV) {
     ST(0) = (SV *)AllPurposeHV;
   } else {
-    ST(0) = &sv_undef;
+    ST(0) = &PL_sv_undef;
   }
 }
 
