Index: trunk/src/reglookup.c
===================================================================
--- src/reglookup.c	(revision 7)
+++ trunk/src/reglookup.c	(revision 17)
@@ -2,5 +2,5 @@
  * $Id$
  *
- * A utility to edit a Windows NT/2K etc registry file.
+ * A utility to read a Windows NT/2K etc registry file.
  *
  * This code was taken from Richard Sharpe''s editreg utility, in the 
@@ -332,4 +332,6 @@
 #define REG_TYPE_DWORD     4
 #define REG_TYPE_MULTISZ   7
+/* Not a real type in the registry */
+#define REG_TYPE_KEY       255
 
 typedef struct _val_str { 
@@ -403,5 +405,5 @@
 
 char* prefix_filter = "";
-char* type_filter = "";
+int type_filter = 0;
 bool type_filter_enabled = false;
 
@@ -424,17 +426,18 @@
 
 
-/* Returns a newly malloc()ed string which contains original string, 
+/* Returns a newly malloc()ed string which contains original buffer,
  * except for non-printable or special characters are quoted in hex
  * with the syntax '\xQQ' where QQ is the hex ascii value of the quoted
- * character.
- */
-static
-char* quote_string(const char* str, char* special)
+ * character.  A null terminator is added, as only ascii, not binary, 
+ * is returned.
+ */
+static
+char* quote_buffer(const unsigned char* str, char* special, unsigned int len)
 {
   unsigned int i;
   unsigned int num_written=0;
-  unsigned int len = strlen(str);
   unsigned int out_len = sizeof(char)*len+1;
   char* ret_val = malloc(out_len);
+
   if(ret_val == NULL)
     return NULL;
@@ -445,8 +448,9 @@
     {
       out_len += 3;
+      /* XXX: may not be the most efficient way of getting enough memory. */
       ret_val = realloc(ret_val, out_len);
       if(ret_val == NULL)
 	break;
-      num_written += snprintf(ret_val+num_written, out_len-num_written,
+      num_written += snprintf(ret_val+num_written, (out_len)-num_written,
 			      "\\x%.2X", str[i]);
     }
@@ -458,4 +462,20 @@
   return ret_val;
 }
+
+
+/* Returns a newly malloc()ed string which contains original string, 
+ * except for non-printable or special characters are quoted in hex
+ * with the syntax '\xQQ' where QQ is the hex ascii value of the quoted
+ * character.
+ */
+static
+char* quote_string(const char* str, char* special)
+{
+  unsigned int len = strlen(str);
+  char* ret_val = quote_buffer((const unsigned char*)str, special, len);
+
+  return ret_val;
+}
+
 
 
@@ -533,5 +553,5 @@
   if (str_is_prefix(prefix_filter, new_path))
   {
-    if (!type_filter_enabled || (strcmp(type_filter, "KEY") == 0))
+    if (!type_filter_enabled || (type_filter == REG_TYPE_KEY))
       printf("%s%s:KEY\n", path, key_tree->name);
 
@@ -797,5 +817,5 @@
   /*
    * add the new key at the new slot 
-   * FIXME: Sort the list someday
+   * XXX: Sort the list someday
    */
 
@@ -876,25 +896,41 @@
    { REG_TYPE_DWORD,    "DWORD" },
    { REG_TYPE_MULTISZ,  "MULTI_SZ" },
-   /*   { REG_TYPE_KEY,      "KEY" },*/
+   { REG_TYPE_KEY,      "KEY" },
    { 0, NULL },
 };
 
+
 static
 const char *val_to_str(unsigned int val, const VAL_STR *val_array)
 {
-  int i = 0;
-
-  if (!val_array) return NULL;
-
-  while (val_array[i].val && val_array[i].str) {
-
-    if (val_array[i].val == val) return val_array[i].str;
-    i++;
-
-  }
+  int i;
+
+  if (!val_array) 
+    return NULL;
+
+  for(i=0; val_array[i].val && val_array[i].str; i++) 
+    if (val_array[i].val == val) 
+      return val_array[i].str;
 
   return NULL;
-
-}
+}
+
+
+/* Returns 0 on error */
+static
+int str_to_val(const char* str, const VAL_STR *val_array)
+{
+  int i;
+
+  if (!val_array) 
+    return 0;
+
+  for(i=0; val_array[i].val && val_array[i].str; i++) 
+    if (strcmp(val_array[i].str, str) == 0) 
+      return val_array[i].val;
+
+  return 0;
+}
+
 
 /*
@@ -947,5 +983,5 @@
       return NULL;
     
-    /* FIXME. This has to be fixed. It has to be UNICODE */ 
+    /* XXX: This has to be fixed. It has to be UNICODE */
     uni_to_ascii(datap, ascii, len, ascii_max);
     return ascii;
@@ -963,18 +999,5 @@
 
   case REG_TYPE_BIN:
-    ascii_max = sizeof(char)*len*3;
-    ascii = malloc(ascii_max+4);
-    if(ascii == NULL)
-      return NULL;
-
-    asciip = ascii;
-    for (i=0; (i<len)&&(i+1)*3<ascii_max; i++) { 
-      int str_rem = ascii_max - ((int)asciip - (int)ascii);
-      asciip += snprintf((char*)asciip, str_rem, "%02x", 
-			 *(unsigned char *)(datap+i));
-      if (i < len && str_rem > 0)
-	*asciip = ' '; asciip++;	
-    }
-    *asciip = '\0';
+    ascii = (unsigned char*)quote_buffer(datap, "\\", len);
     return ascii;
     break;
@@ -1025,4 +1048,5 @@
       {
 	uni_to_ascii(cur_str, cur_ascii, cur_str_max, 0);
+	/* XXX: Should backslashes be quoted as well? */
 	cur_quoted = quote_string((char*)cur_ascii, "|");
 	alen = snprintf((char*)asciip, str_rem, "%s", cur_quoted);
@@ -1259,5 +1283,6 @@
   tmp = (ACE *)malloc(sizeof(ACE));
 
-  if (!tmp) return NULL;
+  if (!tmp) 
+    return NULL;
 
   tmp->type = CVAL(&ace->type);
@@ -1292,5 +1317,5 @@
     tmp->aces[i] = dup_ace(ace);
     ace = (REG_ACE *)((char *)ace + SVAL(&ace->length));
-    /* XXX: FIXME, should handle malloc errors */
+    /* XXX: should handle NULLs returned from dup_ace() */
   }
 
@@ -1493,10 +1518,9 @@
     { /* The data is pointed to by the offset */
       char *dat_ptr = LOCN(regf->base, dat_off);
-      /* XXX: replace with memcpy */
-      bcopy(dat_ptr, dtmp, dat_len);
+      memcpy(dtmp, dat_ptr, dat_len);
     }
     else { /* The data is in the offset or type */
       /*
-       * FIXME.
+       * XXX:
        * Some registry files seem to have wierd fields. If top bit is set,
        * but len is 0, the type seems to be the value ...
@@ -1504,6 +1528,5 @@
        */
       dat_len = dat_len & 0x7FFFFFFF;
-      /* XXX: replace with memcpy */
-      bcopy(&dat_off, dtmp, dat_len);
+      memcpy(dtmp, &dat_off, dat_len);
     }
 
@@ -1564,5 +1587,5 @@
 
  error:
-  /* XXX: FIXME, free the partially allocated structure */
+  /* XXX: free the partially allocated structure */
   return NULL;
 } 
@@ -1710,8 +1733,8 @@
     
     /*
+     * XXX:
      * I am keeping class name as an ascii string for the moment.
      * That means it needs to be converted on output.
      * It will also piss off people who need Unicode/UTF-8 strings. Sorry. 
-     * XXX: FIXME
      */
     tmp->class_name = strdup((char*)cls_name);
@@ -2099,10 +2122,8 @@
   unsigned char* data_asc;
   char* new_path;
-  const char* str_type = val_to_str(val_type,reg_type_names);
+  const char* str_type;
 
   if(!val_name)
     val_name = "";
-  if(!str_type)
-    str_type = "";
   if(!path)
     path = "";
@@ -2117,8 +2138,12 @@
   if (str_is_prefix(prefix_filter, new_path))
   {
-    if (!type_filter_enabled || (strcmp(type_filter, str_type) == 0))
+    if (!type_filter_enabled || (type_filter == val_type))
     {
       if(!val_name)
 	val_name = "<No Name>";
+
+      str_type = val_to_str(val_type,reg_type_names);
+      if(!str_type)
+	str_type = "";
       
       data_asc = data_to_ascii((unsigned char *)data_blk, data_len, val_type);
@@ -2137,5 +2162,6 @@
 {
   fprintf(stderr, "Usage: readreg [-f<PREFIX_FILTER>] [-t<TYPE_FILTER>] "
-                  "[-v] [-p] [-k] [-s] <REGISTRY_FILE>\n");
+                  "[-v] [-s] <REGISTRY_FILE>\n");
+  /* XXX: replace version string with Subversion tag? */
   fprintf(stderr, "Version: 0.1\n");
   fprintf(stderr, "\n\t-v\t sets verbose mode.");
@@ -2165,5 +2191,5 @@
    */
 
-  while ((opt = getopt(argc, argv, "svkf:t:o:c:")) != EOF)
+  while ((opt = getopt(argc, argv, "svf:t:o:c:")) != EOF)
   {
     switch (opt)
@@ -2176,8 +2202,5 @@
 
     case 't':
-      /* XXX: this should be converted to the integer form of types up front,
-       *      and then used to filter with a simple comparison later.
-       */
-      type_filter = strdup(optarg);
+      type_filter = str_to_val(optarg, reg_type_names);
       type_filter_enabled = true;
       regf_opt++;
@@ -2186,5 +2209,5 @@
     case 's':
       print_security++;
-      full_print++;
+      /*full_print++;*/
       regf_opt++;
       break;
@@ -2192,8 +2215,4 @@
     case 'v':
       verbose++;
-      regf_opt++;
-      break;
-
-    case 'k':
       regf_opt++;
       break;
