Index: trunk/lib/regfi.c
===================================================================
--- trunk/lib/regfi.c	(revision 137)
+++ trunk/lib/regfi.c	(revision 138)
@@ -37,31 +37,49 @@
 /******************************************************************************
  ******************************************************************************/
-void regfi_add_message(REGFI_FILE* file, const char* fmt, ...)
+void regfi_add_message(REGFI_FILE* file, uint16 msg_type, const char* fmt, ...)
 {
   /* XXX: This function is not particularly efficient,
    *      but then it is mostly used during errors. 
    */
-  /* XXX: Should we add support for filtering by levels of severity? */
   uint32 buf_size, buf_used;
   char* new_msg;
   va_list args;
 
-  if(file->last_message == NULL)
-    buf_used = 0;
-  else
-    buf_used = strlen(file->last_message);
-
-  buf_size = buf_used+strlen(fmt)+2+128;
-  new_msg = realloc(file->last_message, buf_size);
-  if(new_msg == NULL)
-    /* XXX: should we report this? */
-    return;
-  
-  va_start(args, fmt);
-  vsnprintf(new_msg+buf_used, buf_size-buf_used, fmt, args);
-  va_end(args);
-  strncat(new_msg, "\n", buf_size-1);
-
-  file->last_message = new_msg;
+  if((file->msg_mask & msg_type) != 0)
+  {
+    if(file->last_message == NULL)
+      buf_used = 0;
+    else
+      buf_used = strlen(file->last_message);
+    
+    buf_size = buf_used+strlen(fmt)+160;
+    new_msg = realloc(file->last_message, buf_size);
+    if(new_msg == NULL)
+      /* XXX: should we report this? */
+      return;
+
+    switch (msg_type)
+    {
+    case REGFI_MSG_INFO:
+      strcpy(new_msg+buf_used, "INFO: ");
+      buf_used += 6;
+      break;
+    case REGFI_MSG_WARN:
+      strcpy(new_msg+buf_used, "WARN: ");
+      buf_used += 6;
+      break;
+    case REGFI_MSG_ERROR:
+      strcpy(new_msg+buf_used, "ERROR: ");
+      buf_used += 7;
+      break;
+    }
+
+    va_start(args, fmt);
+    vsnprintf(new_msg+buf_used, buf_size-buf_used, fmt, args);
+    va_end(args);
+    strncat(new_msg, "\n", buf_size-1);
+    
+    file->last_message = new_msg;
+  }
 }
 
@@ -75,4 +93,10 @@
 
   return ret_val;
+}
+
+
+void regfi_set_message_mask(REGFI_FILE* file, uint16 mask)
+{
+  file->msg_mask = mask;
 }
 
@@ -702,5 +726,5 @@
 		       &cell_length, &unalloc))
   {
-    regfi_add_message(file, "ERROR: Could not parse SK record cell"
+    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse SK record cell"
 		      " at offset 0x%.8X.", offset);
     return NULL;
@@ -709,6 +733,6 @@
   if(sk_header[0] != 's' || sk_header[1] != 'k')
   {
-    regfi_add_message(file, "ERROR: Magic number mismatch in parsing SK record"
-		      " at offset 0x%.8X.", offset);
+    regfi_add_message(file, REGFI_MSG_WARN, "Magic number mismatch in parsing"
+		      " SK record at offset 0x%.8X.", offset);
     return NULL;
   }
@@ -729,6 +753,6 @@
      || (strict && ret_val->cell_size != (ret_val->cell_size & 0xFFFFFFF8)))
   {
-    regfi_add_message(file, "ERROR: Invalid cell size found while parsing SK"
-		      " record at offset 0x%.8X.", offset);
+    regfi_add_message(file, REGFI_MSG_WARN, "Invalid cell size found while"
+		      " parsing SK record at offset 0x%.8X.", offset);
     free(ret_val);
     return NULL;
@@ -747,6 +771,7 @@
   if(ret_val->desc_size + REGFI_SK_MIN_LENGTH > ret_val->cell_size)
   {
-    regfi_add_message(file, "ERROR: Security descriptor too large for cell"
-		      " while parsing SK record at offset 0x%.8X.", offset);
+    regfi_add_message(file, REGFI_MSG_ERROR, "Security descriptor too large for"
+		      " cell while parsing SK record at offset 0x%.8X.", 
+		      offset);
     free(ret_val);
     return NULL;
@@ -764,6 +789,7 @@
      || length != ret_val->desc_size)
   {
-    regfi_add_message(file, "ERROR: Failed to read security descriptor"
-		      " while parsing SK record at offset 0x%.8X.", offset);
+    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read security"
+		      " descriptor while parsing SK record at offset 0x%.8X.",
+		      offset);
     free(ret_val);
     return NULL;
@@ -772,6 +798,7 @@
   if(!(ret_val->sec_desc = winsec_parse_desc(sec_desc_buf, ret_val->desc_size)))
   {
-    regfi_add_message(file, "ERROR: Failed to parse security descriptor"
-		      " while parsing SK record at offset 0x%.8X.", offset);
+    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to parse security"
+		      " descriptor while parsing SK record at offset 0x%.8X.",
+		      offset);
     free(sec_desc_buf);
     free(ret_val);
@@ -794,5 +821,5 @@
   if(!regfi_parse_cell(file->fd, offset, NULL, 0, &cell_length, &unalloc))
   {
-    regfi_add_message(file, "ERROR: Failed to read cell header"
+    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read cell header"
 		      " while parsing value list at offset 0x%.8X.", offset);
     return NULL;
@@ -807,5 +834,5 @@
   if((num_values * sizeof(uint32)) > cell_length-sizeof(uint32))
   {
-    regfi_add_message(file, "ERROR: Too many values found"
+    regfi_add_message(file, REGFI_MSG_ERROR, "Too many values found"
 		      " while parsing value list at offset 0x%.8X.", offset);
     return NULL;
@@ -820,5 +847,5 @@
   if((regfi_read(file->fd, (uint8*)ret_val, &length) != 0) || length != read_len)
   {
-    regfi_add_message(file, "ERROR: Failed to read value pointers"
+    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read value pointers"
 		      " while parsing value list at offset 0x%.8X.", offset);
     free(ret_val);
@@ -837,7 +864,7 @@
 	 || ((ret_val[i] & 0xFFFFFFF8) != ret_val[i]))
       {
-	regfi_add_message(file, "ERROR: Invalid value pointer (0x%.8X) found"
-			  " while parsing value list at offset 0x%.8X.", 
-			  ret_val[i], offset);
+	regfi_add_message(file, REGFI_MSG_ERROR, "Invalid value pointer"
+			  " (0x%.8X) found while parsing value list at offset"
+			  " 0x%.8X.", ret_val[i], offset);
 	free(ret_val);
 	return NULL;
@@ -934,5 +961,5 @@
   if ((nk = regfi_parse_nk(file, offset, max_length, true)) == NULL)
   {
-    regfi_add_message(file, "ERROR: Could not load NK record at"
+    regfi_add_message(file, REGFI_MSG_ERROR, "Could not load NK record at"
 		      " offset 0x%.8X.", offset);
     return NULL;
@@ -965,5 +992,5 @@
       if(strict && nk->values == NULL)
       {
-	regfi_add_message(file, "ERROR: Could not load value list"
+	regfi_add_message(file, REGFI_MSG_ERROR, "Could not load value list"
 			  " for NK record at offset 0x%.8X.",
 			  offset);
@@ -1111,8 +1138,9 @@
     rla = range_list_add(rb->hbins, hbin->file_off, hbin->block_size, hbin);
     hbin_off = hbin->file_off + hbin->block_size;
-    /*fprintf(stderr, "file_length=%.8X,hbin_off=%.8X,hbin->block_size=%.8X,hbin->next_block=%.8X\n", 
-      file_length, hbin_off, hbin->block_size, hbin->next_block);*/
     hbin = regfi_parse_hbin(rb, hbin_off, true);
   }
+
+  /* Default message mask */
+  rb->msg_mask = REGFI_MSG_ERROR|REGFI_MSG_WARN;
 
   /* success */
@@ -1661,5 +1689,5 @@
   if(lseek(file->fd, offset, SEEK_SET) == -1)
   {
-    regfi_add_message(file, "ERROR: Seek failed"
+    regfi_add_message(file, REGFI_MSG_ERROR, "Seek failed"
 		      " while parsing hbin at offset 0x%.8X.", offset);
     return NULL;
@@ -1673,5 +1701,5 @@
   if(lseek(file->fd, offset, SEEK_SET) == -1)
   {
-    regfi_add_message(file, "ERROR: Seek failed"
+    regfi_add_message(file, REGFI_MSG_ERROR, "Seek failed"
 		      " while parsing hbin at offset 0x%.8X.", offset);
     return NULL;
@@ -1685,8 +1713,8 @@
   if(strict && (memcmp(hbin->magic, "hbin", 4) != 0))
   {
-    /* XXX: add this back in when we have configurable verbosity. */
-    /*    regfi_add_message(file, "INFO: Magic number mismatch (%.2X %.2X %.2X %.2X)"
-		      " while parsing hbin at offset 0x%.8X.", hbin->magic[0],
-		      hbin->magic[1], hbin->magic[2], hbin->magic[3], offset); */
+    regfi_add_message(file, REGFI_MSG_INFO, "Magic number mismatch "
+		      "(%.2X %.2X %.2X %.2X) while parsing hbin at offset"
+		      " 0x%.8X.", hbin->magic[0], hbin->magic[1], 
+		      hbin->magic[2], hbin->magic[3], offset);
     free(hbin);
     return NULL;
@@ -1695,6 +1723,4 @@
   hbin->first_hbin_off = IVAL(hbin_header, 0x4);
   hbin->block_size = IVAL(hbin_header, 0x8);
-    /*fprintf(stderr, "hbin->block_size field => %.8X\n", IVAL(hbin_header, 0x8));*/
-  /*  hbin->block_size = IVAL(hbin_header, 0x8);*/
   /* this should be the same thing as hbin->block_size but just in case */
   hbin->next_block = IVAL(hbin_header, 0x1C);
@@ -1710,5 +1736,5 @@
      || (hbin->block_size & 0xFFFFF000) != hbin->block_size)
   {
-    regfi_add_message(file, "ERROR: The hbin offset is not aligned"
+    regfi_add_message(file, REGFI_MSG_ERROR, "The hbin offset is not aligned"
 		      " or runs off the end of the file"
 		      " while parsing hbin at offset 0x%.8X.", offset);
@@ -1736,5 +1762,5 @@
 		       &cell_length, &unalloc))
   {
-    regfi_add_message(file, "ERROR: Could not parse cell header"
+    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header"
 		      " while parsing NK record at offset 0x%.8X.", offset);
     return NULL;
@@ -1744,6 +1770,6 @@
   if((nk_header[0x0] != 'n') || (nk_header[0x1] != 'k'))
   {
-    regfi_add_message(file, "ERROR: Magic number mismatch in parsing NK record"
-		      " at offset 0x%.8X.", offset);
+    regfi_add_message(file, REGFI_MSG_WARN, "Magic number mismatch in parsing"
+		      " NK record at offset 0x%.8X.", offset);
     return NULL;
   }
@@ -1752,5 +1778,5 @@
   if(ret_val == NULL)
   {
-    regfi_add_message(file, "ERROR: Failed to allocate memory while"
+    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to allocate memory while"
 		      " parsing NK record at offset 0x%.8X.", offset);
     return NULL;
@@ -1765,6 +1791,6 @@
      || (strict && ret_val->cell_size != (ret_val->cell_size & 0xFFFFFFF8)))
   {
-    regfi_add_message(file, "ERROR: A length check failed while parsing"
-		      " NK record at offset 0x%.8X.", offset);
+    regfi_add_message(file, REGFI_MSG_ERROR, "A length check failed while"
+		      " parsing NK record at offset 0x%.8X.", offset);
     free(ret_val);
     return NULL;
@@ -1782,7 +1808,7 @@
      && (ret_val->key_type != REGFI_NK_TYPE_UNKNOWN3))
   {
-    regfi_add_message(file, "WARN: Unknown key type (0x%.4X) while parsing"
-		      " NK record at offset 0x%.8X.", ret_val->key_type,
-		      offset);
+    regfi_add_message(file, REGFI_MSG_WARN, "Unknown key type (0x%.4X) while"
+		      " parsing NK record at offset 0x%.8X.", 
+		      ret_val->key_type, offset);
   }
 
@@ -1825,5 +1851,5 @@
     if(strict)
     {
-      regfi_add_message(file, "ERROR: Contents too large for cell"
+      regfi_add_message(file, REGFI_MSG_ERROR, "Contents too large for cell"
 			" while parsing NK record at offset 0x%.8X.", offset);
       free(ret_val);
@@ -1857,5 +1883,5 @@
      || length != ret_val->name_length)
   {
-    regfi_add_message(file, "ERROR: Failed to read key name"
+    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read key name"
 		      " while parsing NK record at offset 0x%.8X.", offset);
     free(ret_val->keyname);
@@ -1879,6 +1905,7 @@
     {
       ret_val->classname = NULL;
-      regfi_add_message(file, "WARN: Could not find hbin for class name"
-			" while parsing NK record at offset 0x%.8X.", offset);
+      regfi_add_message(file, REGFI_MSG_WARN, "Could not find hbin for class"
+			" name while parsing NK record at offset 0x%.8X.", 
+			offset);
     }
     /* XXX: Should add this back and make it more strict?
@@ -1887,11 +1914,5 @@
     */
   }
-  /*
-if(ret_val->key_type == 0x0000 || ret_val->key_type == 0x4020)
-{
-  fprintf(stderr, "INFO: keyname=%s,classname=%s,unalloc=%d,num_subkeys=%d,num_values=%d\n",
-	  ret_val->keyname,ret_val->classname,unalloc,ret_val->num_subkeys,ret_val->num_values);
-}
-  */
+
   return ret_val;
 }
@@ -1911,5 +1932,5 @@
     if(!regfi_parse_cell(file->fd, offset, NULL, 0, &cell_length, &unalloc))
     {
-      regfi_add_message(file, "ERROR: Could not parse cell header"
+      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header"
 			" while parsing class name at offset 0x%.8X.", offset);
 	return NULL;
@@ -1918,5 +1939,5 @@
     if((cell_length & 0xFFFFFFF8) != cell_length)
     {
-      regfi_add_message(file, "ERROR: Cell length not a multiple of 8"
+      regfi_add_message(file, REGFI_MSG_ERROR, "Cell length not a multiple of 8"
 			" while parsing class name at offset 0x%.8X.", offset);
       return NULL;
@@ -1925,6 +1946,7 @@
     if(cell_length > max_size)
     {
-      regfi_add_message(file, "WARN: Cell stretches past hbin boundary"
-			" while parsing class name at offset 0x%.8X.", offset);
+      regfi_add_message(file, REGFI_MSG_WARN, "Cell stretches past hbin "
+			"boundary while parsing class name at offset 0x%.8X.",
+			offset);
       if(strict)
 	return NULL;
@@ -1934,6 +1956,7 @@
     if((cell_length - 4) < *name_length)
     {
-      regfi_add_message(file, "WARN: Class name is larger than cell_length"
-			" while parsing class name at offset 0x%.8X.", offset);
+      regfi_add_message(file, REGFI_MSG_WARN, "Class name is larger than"
+			" cell_length while parsing class name at offset"
+			" 0x%.8X.", offset);
       if(strict)
 	return NULL;
@@ -1948,5 +1971,5 @@
 	 || length != *name_length)
       {
-	regfi_add_message(file, "ERROR: Could not read class name"
+	regfi_add_message(file, REGFI_MSG_ERROR, "Could not read class name"
 			  " while parsing class name at offset 0x%.8X.", offset);
 	free(ret_val);
@@ -1975,5 +1998,5 @@
 		       &cell_length, &unalloc))
   {
-    regfi_add_message(file, "ERROR: Could not parse cell header"
+    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header"
 		      " while parsing VK record at offset 0x%.8X.", offset);
     return NULL;
@@ -1992,5 +2015,5 @@
      || ret_val->cell_size != (ret_val->cell_size & 0xFFFFFFF8))
   {
-    regfi_add_message(file, "ERROR: Invalid cell size encountered"
+    regfi_add_message(file, REGFI_MSG_WARN, "Invalid cell size encountered"
 		      " while parsing VK record at offset 0x%.8X.", offset);
     free(ret_val);
@@ -2006,5 +2029,5 @@
      *      0xFFFF. 
      */
-    regfi_add_message(file, "ERROR: Magic number mismatch"
+    regfi_add_message(file, REGFI_MSG_WARN, "Magic number mismatch"
 		      " while parsing VK record at offset 0x%.8X.", offset);
     free(ret_val);
@@ -2025,6 +2048,7 @@
     if(ret_val->name_length + REGFI_VK_MIN_LENGTH + 4 > ret_val->cell_size)
     {
-      regfi_add_message(file, "WARN: Name too long for remaining cell space"
-			" while parsing VK record at offset 0x%.8X.", offset);
+      regfi_add_message(file, REGFI_MSG_WARN, "Name too long for remaining cell"
+			" space while parsing VK record at offset 0x%.8X.",
+			offset);
       if(strict)
       {
@@ -2052,5 +2076,5 @@
        || length != ret_val->name_length)
     {
-      regfi_add_message(file, "ERROR: Could not read value name"
+      regfi_add_message(file, REGFI_MSG_ERROR, "Could not read value name"
 			" while parsing VK record at offset 0x%.8X.", offset);
       free(ret_val->valuename);
@@ -2093,5 +2117,5 @@
       else
       {
-	regfi_add_message(file, "WARN: Could not find hbin for data"
+	regfi_add_message(file, REGFI_MSG_WARN, "Could not find hbin for data"
 			  " while parsing VK record at offset 0x%.8X.", offset);
 	ret_val->data = NULL;
@@ -2101,5 +2125,5 @@
     if(ret_val->data == NULL)
     {
-      regfi_add_message(file, "WARN: Could not parse data record"
+      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse data record"
 			" while parsing VK record at offset 0x%.8X.", offset);
     }
@@ -2124,5 +2148,5 @@
     if(length > 4)
     {
-      regfi_add_message(file, "ERROR: Data in offset but length > 4"
+      regfi_add_message(file, REGFI_MSG_ERROR, "Data in offset but length > 4"
 			" while parsing data record at offset 0x%.8X.", 
 			offset);
@@ -2141,5 +2165,5 @@
 			 &cell_length, &unalloc))
     {
-      regfi_add_message(file, "ERROR: Could not parse cell while"
+      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while"
 			" parsing data record at offset 0x%.8X.", offset);
       return NULL;
@@ -2148,5 +2172,5 @@
     if((cell_length & 0xFFFFFFF8) != cell_length)
     {
-      regfi_add_message(file, "ERROR: Cell length not multiple of 8"
+      regfi_add_message(file, REGFI_MSG_WARN, "Cell length not multiple of 8"
 			" while parsing data record at offset 0x%.8X.",
 			offset);
@@ -2156,5 +2180,5 @@
     if(cell_length > max_size)
     {
-      regfi_add_message(file, "WARN: Cell extends past hbin boundary"
+      regfi_add_message(file, REGFI_MSG_WARN, "Cell extends past hbin boundary"
 			" while parsing data record at offset 0x%.8X.", 
 			offset);
@@ -2171,5 +2195,5 @@
        *      such as 53392.
        */
-      regfi_add_message(file, "WARN: Data length (0x%.8X) larger than"
+      regfi_add_message(file, REGFI_MSG_WARN, "Data length (0x%.8X) larger than"
 			" remaining cell length (0x%.8X)"
 			" while parsing data record at offset 0x%.8X.", 
@@ -2188,5 +2212,5 @@
        || read_length != length)
     {
-      regfi_add_message(file, "ERROR: Could not read data block while"
+      regfi_add_message(file, REGFI_MSG_ERROR, "Could not read data block while"
 			" parsing data record at offset 0x%.8X.", offset);
       free(ret_val);
