diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG
index c761d668a5aa103b554bb3a3d4e3a12c8cfcb6ac..834f014f3cd944b86307759724f60fe04b9c59b0 100644
--- a/sm5/CHANGELOG
+++ b/sm5/CHANGELOG
@@ -1,6 +1,6 @@
 CHANGELOG for smartmontools
 
-$Id: CHANGELOG,v 1.12 2002/10/21 16:00:46 ballen4705 Exp $
+$Id: CHANGELOG,v 1.13 2002/10/22 11:40:52 ballen4705 Exp $
 
 Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
 
@@ -29,6 +29,12 @@ NOTES FOR NEXT RELEASE:
 
 smartmontools-5.0-11
 
+    Modified function that prints vendor attributes to say if the
+    attribute has currently failed or has ever failed.
+
+    -p option now prints out license info and CVS strings for all
+    modules in the code.
+
     Previous versions of this code (and Smartsuite) only generate
     SMART failure errors if the value of an attribute is below the
     threshold and the prefailure bit is set.  However the ATA Spec
diff --git a/sm5/ataprint.c b/sm5/ataprint.c
index e59f58dbe524843340552d7c3f9859ece529475b..2a2d6680f5b2a952257228131679e288c78f9e9d 100644
--- a/sm5/ataprint.c
+++ b/sm5/ataprint.c
@@ -28,7 +28,7 @@
 #include "smartctl.h"
 #include "extern.h"
 
-const char *CVSid4="$Id: ataprint.c,v 1.17 2002/10/22 09:56:38 ballen4705 Exp $\n"
+const char *CVSid4="$Id: ataprint.c,v 1.18 2002/10/22 11:40:52 ballen4705 Exp $\n"
 	           "\t" CVSID2 "\t" CVSID3 "\t" CVSID6 ;
 
 // Function for printing ASCII byte-swapped strings, skipping white
@@ -357,61 +357,96 @@ void PrintSmartExtendedSelfTestPollingTime ( struct ata_smart_values data)
 }
 
 
+// onlyfailing is a bitflag
+// onlyfailing=0 : all values
+// onlyfailing=1:  just ones that are currently failed and have prefailure bit set
+// onlyfailing=2:  ones that are failed, or have failed with or without prefailure bit set
+void PrintSmartAttribWithThres (struct ata_smart_values data, 
+				struct ata_smart_thresholds thresholds,
+				int onlyfailed){
+  int i,j;
+  long long rawvalue;
+  int needheader=1;
+    
+  // step through all vendor attributes
+  for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
+    char *status;
+    struct ata_smart_attribute *disk=data.vendor_attributes+i;
+    struct ata_smart_threshold_entry *thre=thresholds.thres_entries+i;
+    
+    // consider only valid attributes
+    if (disk->id && thre->id){
+      char *type;
+      int failednow,failedever;
 
-void PrintSmartAttribWithThres ( struct ata_smart_values data, 
-                                 struct ata_smart_thresholds thresholds)
-{
-   int i,j;
-   long long rawvalue; 
-   printf ("Vendor Specific SMART Attributes with Thresholds:\n");
-   printf ("Revision Number: %i\n", data.revnumber);
-   printf ("Attribute                    Flag     Value Worst Threshold Raw Value\n");
-	
-   for ( i = 0 ; i < NUMBER_ATA_SMART_ATTRIBUTES ; i++ ){
-     // step through all vendor attributes
-     if (data.vendor_attributes[i].id && thresholds.thres_entries[i].id){
-       ataPrintSmartAttribName(data.vendor_attributes[i].id);
-       // printing if they contain something sensible
-       printf(" 0x%04x   %.3i   %.3i   %.3i       ", 
-	      data.vendor_attributes[i].status.all,
-	      data.vendor_attributes[i].current,
-	      data.vendor_attributes[i].worst,
-	      thresholds.thres_entries[i].threshold);
-
-       // convert the six individual bytes to a long long (8 byte) integer
-       rawvalue = 0;
-       for (j = 0 ; j < 6 ; j++)
-	 rawvalue |= data.vendor_attributes[i].raw[j] << (8*j) ;
-
-       // This switch statement is where we handle Raw attributes
-       // that are stored in an unusual vendor-specific format,
-       switch (data.vendor_attributes[i].id){
-
-	 // Power on time
-       case 9:
-	 if (smart009minutes)
-	   // minutes
-	   printf ("%llu h + %2llu m\n",rawvalue/60,rawvalue%60);
-	 else
+      failednow =disk->current <= thre->threshold;
+      failedever=disk->worst   <= thre->threshold;
+      
+      // These break out of the loop if we are only printing certain entries...
+      if (onlyfailed==1 && (!disk->status.flag.prefailure || !failednow))
+	break;
+      
+      if (onlyfailed==2 && !failedever)
+	break;
+      
+      // print header only if needed
+      if (needheader){
+	printf ("SMART Data Structure revision number: %i\n",data.revnumber);
+	printf ("Vendor Specific SMART Attributes with Thresholds:\n"
+		"Attribute                    Flag     Value Worst Threshold Type     Ever_Failed? Raw_Value\n");
+	needheader=0;
+      }
+      
+      // is this currently failed, or has it ever failed?
+      if (failednow)
+	status="FAILED NOW";
+      else if (failedever)
+	status="In the past";
+      else
+	status="    -";
+      
+      // Print name of attribute
+      ataPrintSmartAttribName(disk->id);
+      
+      // printing line for each valid attribute
+      type=disk->status.flag.prefailure?"Pre-fail":"Old age";
+      printf(" 0x%04x   %.3i   %.3i   %.3i       %-9s%-13s", 
+	     disk->status.all, disk->current, disk->worst,
+	     thre->threshold, type, status);
+      
+      // convert the six individual bytes to a long long (8 byte) integer
+      rawvalue = 0;
+      for (j = 0 ; j < 6 ; j++)
+	rawvalue |= disk->raw[j] << (8*j) ;
+      
+      // This switch statement is where we handle Raw attributes
+      // that are stored in an unusual vendor-specific format,
+      switch (disk->id){
+	// Power on time
+      case 9:
+	if (smart009minutes)
+	  // minutes
+	  printf ("%llu h + %2llu m\n",rawvalue/60,rawvalue%60);
+	else
 	   // hours
-	   printf ("%llu\n", rawvalue);  //stored in hours
-	 break;
-	 
-	 // Temperature
-       case 194:
-	 printf ("%u", data.vendor_attributes[i].raw[0]);
-	 if (rawvalue==data.vendor_attributes[i].raw[0])
-	   printf("\n");
-	 else
-	   // The other bytes are in use. Try IBM's model
-	   printf(" (Lifetime Min/Max %u/%u)\n",data.vendor_attributes[i].raw[2],
-		  data.vendor_attributes[i].raw[4]);
-	 break;
-       default:
-	 printf("%llu\n", rawvalue);
-       }	    
-     }
-   }
+	  printf ("%llu\n", rawvalue);  //stored in hours
+	break;
+	
+	// Temperature
+      case 194:
+	printf ("%u", disk->raw[0]);
+	if (rawvalue==disk->raw[0])
+	  printf("\n");
+	else
+	  // The other bytes are in use. Try IBM's model
+	  printf(" (Lifetime Min/Max %u/%u)\n",disk->raw[2],
+		 disk->raw[4]);
+	break;
+      default:
+	printf("%llu\n", rawvalue);
+      }	    
+    }
+  }
 }
 
 
@@ -907,7 +942,7 @@ void ataPrintMain (int fd){
   
   // Print vendor-specific attributes
   if (smartvendorattrib)
-    PrintSmartAttribWithThres(smartval, smartthres);
+    PrintSmartAttribWithThres(smartval, smartthres,0);
 	
   // Print SMART error log
   if (smarterrorlog){
diff --git a/sm5/ataprint.cpp b/sm5/ataprint.cpp
index e4e5992ef0e233d0ecda3045227dc05be2c5fa25..a5db468359adb9629b4ea4a933e7e02ed2a361c4 100644
--- a/sm5/ataprint.cpp
+++ b/sm5/ataprint.cpp
@@ -28,7 +28,7 @@
 #include "smartctl.h"
 #include "extern.h"
 
-const char *CVSid4="$Id: ataprint.cpp,v 1.17 2002/10/22 09:56:38 ballen4705 Exp $\n"
+const char *CVSid4="$Id: ataprint.cpp,v 1.18 2002/10/22 11:40:52 ballen4705 Exp $\n"
 	           "\t" CVSID2 "\t" CVSID3 "\t" CVSID6 ;
 
 // Function for printing ASCII byte-swapped strings, skipping white
@@ -357,61 +357,96 @@ void PrintSmartExtendedSelfTestPollingTime ( struct ata_smart_values data)
 }
 
 
+// onlyfailing is a bitflag
+// onlyfailing=0 : all values
+// onlyfailing=1:  just ones that are currently failed and have prefailure bit set
+// onlyfailing=2:  ones that are failed, or have failed with or without prefailure bit set
+void PrintSmartAttribWithThres (struct ata_smart_values data, 
+				struct ata_smart_thresholds thresholds,
+				int onlyfailed){
+  int i,j;
+  long long rawvalue;
+  int needheader=1;
+    
+  // step through all vendor attributes
+  for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
+    char *status;
+    struct ata_smart_attribute *disk=data.vendor_attributes+i;
+    struct ata_smart_threshold_entry *thre=thresholds.thres_entries+i;
+    
+    // consider only valid attributes
+    if (disk->id && thre->id){
+      char *type;
+      int failednow,failedever;
 
-void PrintSmartAttribWithThres ( struct ata_smart_values data, 
-                                 struct ata_smart_thresholds thresholds)
-{
-   int i,j;
-   long long rawvalue; 
-   printf ("Vendor Specific SMART Attributes with Thresholds:\n");
-   printf ("Revision Number: %i\n", data.revnumber);
-   printf ("Attribute                    Flag     Value Worst Threshold Raw Value\n");
-	
-   for ( i = 0 ; i < NUMBER_ATA_SMART_ATTRIBUTES ; i++ ){
-     // step through all vendor attributes
-     if (data.vendor_attributes[i].id && thresholds.thres_entries[i].id){
-       ataPrintSmartAttribName(data.vendor_attributes[i].id);
-       // printing if they contain something sensible
-       printf(" 0x%04x   %.3i   %.3i   %.3i       ", 
-	      data.vendor_attributes[i].status.all,
-	      data.vendor_attributes[i].current,
-	      data.vendor_attributes[i].worst,
-	      thresholds.thres_entries[i].threshold);
-
-       // convert the six individual bytes to a long long (8 byte) integer
-       rawvalue = 0;
-       for (j = 0 ; j < 6 ; j++)
-	 rawvalue |= data.vendor_attributes[i].raw[j] << (8*j) ;
-
-       // This switch statement is where we handle Raw attributes
-       // that are stored in an unusual vendor-specific format,
-       switch (data.vendor_attributes[i].id){
-
-	 // Power on time
-       case 9:
-	 if (smart009minutes)
-	   // minutes
-	   printf ("%llu h + %2llu m\n",rawvalue/60,rawvalue%60);
-	 else
+      failednow =disk->current <= thre->threshold;
+      failedever=disk->worst   <= thre->threshold;
+      
+      // These break out of the loop if we are only printing certain entries...
+      if (onlyfailed==1 && (!disk->status.flag.prefailure || !failednow))
+	break;
+      
+      if (onlyfailed==2 && !failedever)
+	break;
+      
+      // print header only if needed
+      if (needheader){
+	printf ("SMART Data Structure revision number: %i\n",data.revnumber);
+	printf ("Vendor Specific SMART Attributes with Thresholds:\n"
+		"Attribute                    Flag     Value Worst Threshold Type     Ever_Failed? Raw_Value\n");
+	needheader=0;
+      }
+      
+      // is this currently failed, or has it ever failed?
+      if (failednow)
+	status="FAILED NOW";
+      else if (failedever)
+	status="In the past";
+      else
+	status="    -";
+      
+      // Print name of attribute
+      ataPrintSmartAttribName(disk->id);
+      
+      // printing line for each valid attribute
+      type=disk->status.flag.prefailure?"Pre-fail":"Old age";
+      printf(" 0x%04x   %.3i   %.3i   %.3i       %-9s%-13s", 
+	     disk->status.all, disk->current, disk->worst,
+	     thre->threshold, type, status);
+      
+      // convert the six individual bytes to a long long (8 byte) integer
+      rawvalue = 0;
+      for (j = 0 ; j < 6 ; j++)
+	rawvalue |= disk->raw[j] << (8*j) ;
+      
+      // This switch statement is where we handle Raw attributes
+      // that are stored in an unusual vendor-specific format,
+      switch (disk->id){
+	// Power on time
+      case 9:
+	if (smart009minutes)
+	  // minutes
+	  printf ("%llu h + %2llu m\n",rawvalue/60,rawvalue%60);
+	else
 	   // hours
-	   printf ("%llu\n", rawvalue);  //stored in hours
-	 break;
-	 
-	 // Temperature
-       case 194:
-	 printf ("%u", data.vendor_attributes[i].raw[0]);
-	 if (rawvalue==data.vendor_attributes[i].raw[0])
-	   printf("\n");
-	 else
-	   // The other bytes are in use. Try IBM's model
-	   printf(" (Lifetime Min/Max %u/%u)\n",data.vendor_attributes[i].raw[2],
-		  data.vendor_attributes[i].raw[4]);
-	 break;
-       default:
-	 printf("%llu\n", rawvalue);
-       }	    
-     }
-   }
+	  printf ("%llu\n", rawvalue);  //stored in hours
+	break;
+	
+	// Temperature
+      case 194:
+	printf ("%u", disk->raw[0]);
+	if (rawvalue==disk->raw[0])
+	  printf("\n");
+	else
+	  // The other bytes are in use. Try IBM's model
+	  printf(" (Lifetime Min/Max %u/%u)\n",disk->raw[2],
+		 disk->raw[4]);
+	break;
+      default:
+	printf("%llu\n", rawvalue);
+      }	    
+    }
+  }
 }
 
 
@@ -907,7 +942,7 @@ void ataPrintMain (int fd){
   
   // Print vendor-specific attributes
   if (smartvendorattrib)
-    PrintSmartAttribWithThres(smartval, smartthres);
+    PrintSmartAttribWithThres(smartval, smartthres,0);
 	
   // Print SMART error log
   if (smarterrorlog){
diff --git a/sm5/ataprint.h b/sm5/ataprint.h
index 6564e897342f817138984641027f517b79a12bf5..f76076f8c2c94b9312ee69bad6583c454e934cbe 100644
--- a/sm5/ataprint.h
+++ b/sm5/ataprint.h
@@ -26,7 +26,7 @@
 #define _SMART_PRINT_H_
 
 #ifndef CVSID2
-#define CVSID2 "$Id: ataprint.h,v 1.7 2002/10/22 09:44:55 ballen4705 Exp $\n"
+#define CVSID2 "$Id: ataprint.h,v 1.8 2002/10/22 11:40:52 ballen4705 Exp $\n"
 #endif
 
 #include <stdio.h>
@@ -46,7 +46,8 @@ void ataPrintSmartErrorlog (struct ata_smart_errorlog);
 void PrintSmartAttributes (struct ata_smart_values data);
 
 void PrintSmartAttribWithThres (struct ata_smart_values data,
-                                struct ata_smart_thresholds thresholds);
+                                struct ata_smart_thresholds thresholds,
+				int onlyfailed);
 
 void ataPrintSmartSelfTestlog (struct ata_smart_selftestlog data);