Index: trunk/src/reglookup.c
===================================================================
--- trunk/src/reglookup.c	(revision 80)
+++ trunk/src/reglookup.c	(revision 81)
@@ -3,5 +3,5 @@
  * Gerald Carter''s regfio interface.
  *
- * Copyright (C) 2005-2006 Timothy D. Morgan
+ * Copyright (C) 2005-2007 Timothy D. Morgan
  * Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com
  *
@@ -382,16 +382,20 @@
 
 
-void_stack* path2Stack(const char* s)
-{
-  void_stack* ret_val;
-  void_stack* rev_ret = void_stack_new(REGF_MAX_DEPTH);
+char** splitPath(const char* s)
+{
+  char** ret_val;
   const char* cur = s;
   char* next = NULL;
   char* copy;
-
-  if (rev_ret == NULL)
+  uint32 ret_cur = 0;
+
+  ret_val = (char**)malloc((REGF_MAX_DEPTH+1+1)*sizeof(char**));
+  if (ret_val == NULL)
     return NULL;
+  ret_val[0] = NULL;
+
+  /* We return a well-formed, 0-length, path even when input is icky. */
   if (s == NULL)
-    return rev_ret;
+    return ret_val;
   
   while((next = strchr(cur, '/')) != NULL)
@@ -405,33 +409,43 @@
       memcpy(copy, cur, next-cur);
       copy[next-cur] = '\0';
-      if(!void_stack_push(rev_ret, copy))
+      ret_val[ret_cur++] = copy;
+      if(ret_cur < (REGF_MAX_DEPTH+1+1))
+	ret_val[ret_cur] = NULL;
+      else
 	bailOut(2, "ERROR: Registry maximum depth exceeded.\n");
     }
     cur = next+1;
   }
+
+  /* Grab last element, if path doesn't end in '/'. */
   if(strlen(cur) > 0)
   {
     copy = strdup(cur);
-    if(!void_stack_push(rev_ret, copy))
+    ret_val[ret_cur++] = copy;
+    if(ret_cur < (REGF_MAX_DEPTH+1+1))
+      ret_val[ret_cur] = NULL;
+    else
       bailOut(2, "ERROR: Registry maximum depth exceeded.\n");
   }
 
-  ret_val = void_stack_copy_reverse(rev_ret);
-  void_stack_free(rev_ret);
-
   return ret_val;
 }
 
-/* Returns a quoted path from an nk_stack */
-char* stack2Path(void_stack* nk_stack)
-{
-  const REGF_NK_REC* cur;
+
+/* Returns a quoted path from an iterator's stack */
+/* XXX: Some way should be found to integrate this into regfi's API 
+ *      The problem is that the escaping is sorta reglookup-specific.
+ */
+char* iter2Path(REGFI_ITERATOR* i)
+{
+  const REGFI_ITER_POSITION* cur;
   uint32 buf_left = 127;
   uint32 buf_len = buf_left+1;
   uint32 name_len = 0;
   uint32 grow_amt;
-  char* buf; 
+  char* buf;
   char* new_buf;
   char* name;
+  const char* cur_name;
   void_stack_iterator* iter;
   
@@ -441,5 +455,5 @@
   buf[0] = '\0';
 
-  iter = void_stack_iterator_new(nk_stack);
+  iter = void_stack_iterator_new(i->key_positions);
   if (iter == NULL)
   {
@@ -449,11 +463,23 @@
 
   /* skip root element */
+  if(void_stack_size(i->key_positions) < 1)
+  {
+    buf[0] = '/';
+    buf[1] = '\0';
+    return buf;
+  }
   cur = void_stack_iterator_next(iter);
 
-  while((cur = void_stack_iterator_next(iter)) != NULL)
-  {
+  do
+  {
+    cur = void_stack_iterator_next(iter);
+    if (cur == NULL)
+      cur_name = i->cur_key->keyname;
+    else
+      cur_name = cur->nk->keyname;
+
     buf[buf_len-buf_left-1] = '/';
     buf_left -= 1;
-    name = quote_string(cur->keyname, key_special_chars);
+    name = quote_string(cur_name, key_special_chars);
     name_len = strlen(name);
     if(name_len+1 > buf_left)
@@ -474,5 +500,5 @@
     buf[buf_len-buf_left-1] = '\0';
     free(name);
-  }
+  } while(cur != NULL);
 
   return buf;
@@ -572,5 +598,5 @@
 
 
-void printValueList(REGFI_ITERATOR i, char* prefix)
+void printValueList(REGFI_ITERATOR* i, char* prefix)
 {
   REGF_VK_REC* value;
@@ -578,6 +604,9 @@
   value = regfi_iterator_first_value(i);
   while(value != NULL)
-    if(!type_filter_enabled || (value.type == type_filter))
+  {
+    if(!type_filter_enabled || (value->type == type_filter))
       printValue(value, prefix);
+    value = regfi_iterator_next_value(i);
+  }
 }
 
@@ -630,89 +659,68 @@
 
 
-void printKeyTree(REGF_FILE* f, void_stack* nk_stack, const char* prefix)
-{
+void printKeyTree(REGFI_ITERATOR* iter)
+{
+  REGF_NK_REC* root = NULL;
   REGF_NK_REC* cur = NULL;
   REGF_NK_REC* sub = NULL;
   char* path = NULL;
-  char* val_path = NULL;
-  uint32 val_path_len = 0;
-  uint32 path_len = 0;
-  uint32 prefix_len = strlen(prefix);
   int key_type = regfi_type_str2val("KEY");
+  bool print_this = true;
+
+  root = cur = regfi_iterator_cur_key(iter);
+  sub = regfi_iterator_first_subkey(iter);
   
-  if((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
-  {
-    cur->subkey_index = 0;
-    path = stack2Path(nk_stack);
-
-    if(print_verbose)
-    {
-      if(prefix[0] == '\0')
-	fprintf(stderr, "VERBOSE: Printing key tree under path: /\n");
-      else
-	fprintf(stderr, "VERBOSE: Printing key tree under path: %s\n",
-		prefix);
-    }
-
-    path_len = strlen(path);
-    val_path_len = prefix_len+path_len;
-    val_path = (char*)malloc(val_path_len+1+1);
-    if(val_path == NULL)
-      bailOut(2, "ERROR: Could not allocate val_path.\n");
-
-    strcpy(val_path, prefix);
-    strcpy(val_path+prefix_len, path);
-    if(val_path[0] == '\0')
-    {
-      val_path[0] = '/';
-      val_path[1] = '\0';
-    }
-    if(!type_filter_enabled || (key_type == type_filter))
-      printKey(cur, val_path);
-    if(!type_filter_enabled || (key_type != type_filter))
-      printValueList(cur, val_path);
+  if(root == NULL)
+    bailOut(3, "ERROR: root cannot be NULL.\n");
+  
+  do
+  {
+    if(print_this)
+    {
+      path = iter2Path(iter);
+      if(path == NULL)
+	bailOut(2, "ERROR: Could not construct iterator's path.\n");
+      
+      if(!type_filter_enabled || (key_type == type_filter))
+	printKey(cur, path);
+      if(!type_filter_enabled || (key_type != type_filter))
+	printValueList(iter, path);
+      
+      free(path);
+    }
     
-    while((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
-    {
-      if((sub = regfi_fetch_subkey(f, cur)) == NULL)
+    if(sub == NULL)
+    {
+      if(cur != root)
       {
-	sub = void_stack_pop(nk_stack);
-	/* XXX: This is just a shallow free.  Need to write deep free
-	 * routines to replace the Samba code for this. 
-	 */ 
-	if(sub != NULL)
-	  free(sub);
+	/* We're done with this sub-tree, going up and hitting other branches. */
+	if(!regfi_iterator_up(iter))
+	  bailOut(3, "ERROR: could not traverse iterator upward.\n");
+	
+	cur = regfi_iterator_cur_key(iter);
+	if(cur == NULL)
+	  bailOut(3, "ERROR: unexpected NULL for key.\n");
+	
+	sub = regfi_iterator_next_subkey(iter);
       }
-      else
-      {
-	sub->subkey_index = 0;
-	if(!void_stack_push(nk_stack, sub))
-	  bailOut(2, "ERROR: Registry maximum depth exceeded.\n");
-	path = stack2Path(nk_stack);
-	if(path != NULL)
-	{
-	  path_len = strlen(path);
-	  if(val_path_len < prefix_len+path_len)
-	  {
-	    val_path_len = prefix_len+path_len;
-	    val_path = (char*)realloc(val_path, val_path_len+1);
-	    if(val_path == NULL)
-	      bailOut(2, "ERROR: Could not reallocate val_path.\n");
-	  }
-	  strcpy(val_path, prefix);
-	  strcpy(val_path+prefix_len, path);
-	  if(!type_filter_enabled || (key_type == type_filter))
-	    printKey(sub, val_path);
-	  if(!type_filter_enabled || (key_type != type_filter))
-	    printValueList(sub, val_path);
-	}
-      }
-    }
-  }
-  if(val_path != NULL)
-    free(val_path);
+      print_this = false;
+    }
+    else
+    { /* We have unexplored sub-keys.  
+       * Let's move down and print this first sub-tree out. 
+       */
+      if(!regfi_iterator_down(iter))
+	bailOut(3, "ERROR: could not traverse iterator downward.\n");
+
+      cur = sub;
+      sub = regfi_iterator_first_subkey(iter);
+      print_this = true;
+    }
+  } while(!((cur == root) && (sub == NULL)));
+
   if(print_verbose)
     fprintf(stderr, "VERBOSE: Finished printing key tree.\n");
 }
+
 
 /*
@@ -724,9 +732,8 @@
 int retrievePath(REGFI_ITERATOR* iter, char** path)
 {
-  REG_VK_REC* value;
+  REGF_VK_REC* value;
+  char* tmp_path_joined;
+  const char** tmp_path;
   uint32 i;
-  char* p;
-  char* tmp_path_joined;
-  char** tmp_path;
   
   if(path == NULL)
@@ -734,5 +741,5 @@
 
   /* One extra for any value at the end, and one more for NULL */
-  tmp_path = (char**)malloc(sizeof(char**)*(REGF_MAX_DEPTH+1+1));
+  tmp_path = (const char**)malloc(sizeof(const char**)*(REGF_MAX_DEPTH+1+1));
   if(tmp_path == NULL)
     return -2;
@@ -763,5 +770,5 @@
 
     value = regfi_iterator_cur_value(iter);
-    tmp_path_joined = joinPath(tmp_path);
+    tmp_path_joined = iter2Path(iter);
 
     if((value == NULL) || (tmp_path_joined == NULL))
@@ -808,8 +815,6 @@
 int main(int argc, char** argv)
 {
-  void_stack* path_stack;
   char** path = NULL;
   REGF_FILE* f;
-  REGF_NK_REC* root;
   REGFI_ITERATOR* iter;
   int retr_path_ret;
@@ -883,7 +888,15 @@
     bailOut(3, "ERROR: Couldn't create registry iterator.\n");
 
+  if(print_header)
+  {
+    if(print_security)
+      printf("PATH,TYPE,VALUE,MTIME,OWNER,GROUP,SACL,DACL\n");
+    else
+      printf("PATH,TYPE,VALUE,MTIME\n");
+  }
+
   if(path_filter_enabled && path_filter != NULL)
     path = splitPath(path_filter);
-  
+
   if(path != NULL)
   {
@@ -892,10 +905,10 @@
       fprintf(stderr, "WARNING: specified path not found.\n");
     else if (retr_path_ret == 2)
-      printKeyTree(iter, path_filter);
+      printKeyTree(iter);
     else if(retr_path_ret != 0)
       bailOut(4, "ERROR: Unknown error occurred in retrieving path.\n");
   }
   else
-    printKeyTree(iter, "");
+    printKeyTree(iter);
 
   regfi_iterator_free(iter);
