Index: /SConstruct
===================================================================
--- /SConstruct	(revision 231)
+++ /SConstruct	(revision 232)
@@ -1,19 +1,24 @@
+import sys
+import os
+
 cflags = '-std=gnu99 -pedantic -Wall -D_FILE_OFFSET_BITS=64 -DREGFI_WIN32'
 
-libiconv_path='win32/libiconv/'
-libpthreads_path='win32/libpthreads/'
+libiconv_path='.export/win32/libiconv/'
+libpthreads_path='.export/win32/libpthreads/'
 libpthread_name='pthreadGC2'
-libtalloc_path='win32/libtalloc/'
+libtalloc_path='.export/win32/libtalloc/'
 
-source_targets=('reglookup-src-trunk.tar.gz',)
-win32_targets=('reglookup-win32-trunk.zip',)
-doc_targets=('reglookup-doc-trunk.tar.gz',)
-all_targets = source_targets+win32_targets+doc_targets 
+source_targets=('src-trunk',)
+win32_targets=('win32-trunk',)
+doc_targets=('doc-trunk',)
+all_targets = source_targets+win32_targets+doc_targets
 
-def target2version(target):
+
+
+def parse_target(target):
     chunks = target.split('-')
-    if len(chunks) != 3:
+    if len(chunks) != 2:
         return None
-    return chunks[2].split('.')[0]
+    return chunks
 
 def version2input(version):
@@ -24,14 +29,27 @@
 
 
-source_cmds='''
-rm -rf .release;
-svn export svn+ssh://sentinelchicken.org/home/projects/subversion/reglookup/$SOURCE .release/%s;
-cd .release/%s && scons doc
-cd .release && tar cf %s.tar %s && gzip -9 %s.tar;
-mv .release/%s.tar.gz . && rm -rf .release
+export_cmds='''
+rm -rf .export
+svn export --depth files svn+ssh://sentinelchicken.org/home/projects/subversion/reglookup .export
+svn export svn+ssh://sentinelchicken.org/home/projects/subversion/reglookup/doc .export/doc
+svn export svn+ssh://sentinelchicken.org/home/projects/subversion/reglookup/win32 .export/win32
+svn export svn+ssh://sentinelchicken.org/home/projects/subversion/reglookup/%s .export/%s
 '''
 
+version_cmds='''
+echo 'REGFI_VERSION="%s"' > .export/%s/regfi_version.py
+'''
+
+cleanup_cmds='''
+rm -rf .export
+'''
+
+source_cmds='''
+cd %s && scons doc
+mv %s %s && tar cf %s.tar %s && gzip -9 %s.tar;
+'''+cleanup_cmds
+
 win32_cmds='''
-rm -rf .release && mkdir -p .release/%s/python/pyregfi
+mkdir -p .release/%s/python/pyregfi
 cp %s/src/*.exe .release/%s
 
@@ -39,31 +57,28 @@
 cp %s/python/pyregfi/*.py .release/%s/python/pyregfi
 
-cp win32/libiconv/bin/*.dll win32/libpthreads/bin/*.dll win32/libtalloc/bin/*.dll trunk/lib/*.dll .release/%s
+cp .export/win32/libiconv/bin/*.dll .export/win32/libpthreads/bin/*.dll .export/win32/libtalloc/bin/*.dll trunk/lib/*.dll .release/%s
 cd .release && zip -r %s.zip %s
 mv .release/%s.zip . && rm -rf .release
-'''
+'''+cleanup_cmds
 
 doc_cmds='''
-rm -rf .release;
-svn export svn+ssh://sentinelchicken.org/home/projects/subversion/reglookup/ .release;
-cd .release && doxygen Doxyfile.regfi
-cd .release && doxygen Doxyfile.pyregfi
-mv .release/doc .release/%s
-cd .release && tar cf %s.tar %s && gzip -9 %s.tar;
-mv .release/%s.tar.gz . && rm -rf .release
-'''
+cd .export && doxygen Doxyfile.regfi
+cd .export && doxygen Doxyfile.pyregfi
+mv .export/doc .export/%s
+cd .export && tar cf %s.tar %s && gzip -9 %s.tar
+mv .export/%s.tar.gz .
+'''+cleanup_cmds
 
 def generate_cmds(source, target, env, for_signature):
     ret_val = ''
+    input_prefix = str(source[0])+'/'
+
     for t in target:
-        t = str(t)
-        t_base = t.split('.tar.gz')[0].split('.zip')[0]
-        if t in source_targets:
-            ret_val += source_cmds % (t_base,t_base,t_base,
-                                      t_base,t_base,t_base)
-        elif t in win32_targets:
-            version = target2version(t)
-            input_prefix = version2input(version)
+        ttype,version = parse_target(str(t))
+        t_base = 'reglookup-%s-%s' % (ttype, version)
 
+        if ttype == 'src':
+            ret_val += source_cmds % (input_prefix, input_prefix, t_base, t_base, t_base, t_base)
+        elif ttype == 'win32':
             env['platform']='cygwin'
             env['CC']='i586-mingw32msvc-cc'
@@ -122,8 +137,8 @@
 
             ret_val += win32_cmds % (t_base,input_prefix,t_base,input_prefix,
-                                     t_base,input_prefix,
-                                     t_base,t_base,t_base,t_base,t_base)
+                                     t_base,input_prefix,t_base,
+                                     t_base,t_base,t_base,t_base)
 
-        elif t in doc_targets:
+        elif ttype == 'doc':
             ret_val += doc_cmds % (t_base,t_base,t_base,t_base,t_base)
         
@@ -131,12 +146,12 @@
 
 
-
 release_builder = Builder(generator = generate_cmds,
-                          suffix = '.tar.gz',
+                          suffix = '',
                           src_suffix = '',
-                          prefix='reglookup-')
-
+                          prefix='')
 
 env = Environment()
+env['ENV']['SSH_AGENT_PID'] = os.environ['SSH_AGENT_PID']
+env['ENV']['SSH_AUTH_SOCK'] = os.environ['SSH_AUTH_SOCK']
 env['BUILDERS']['Release'] = release_builder
 
@@ -145,10 +160,16 @@
 
 for target in COMMAND_LINE_TARGETS:
-    AlwaysBuild(target)
     if target not in all_targets:
         print('ERROR: cannot build "%s".  Acceptable targets: %s'
               % (target, repr(all_targets)))
-        break
-    env.Release(target, Dir(version2input(target2version(target))))
+        sys.exit(1)
+    AlwaysBuild(target)
+    ttype,version = parse_target(target)
+
+    i = version2input(version)
+    env.Execute(export_cmds % (i, i))
+    if version != 'trunk':
+        env.Execute(version_cmds % (version, i))
+    env.Release(target, Dir('.export/'+i))
 
 Default(None)
Index: /doc/TODO
===================================================================
--- /doc/TODO	(revision 231)
+++ /doc/TODO	(revision 232)
@@ -38,2 +38,27 @@
 
  - Grep through the source for 'XXX', and you'll find more.
+
+
+
+1.0 RELEASE
+===========
+
+Add fields/methods for accessing security descriptors in pyregfi
+
+Key caching
+
+Add function to obtain path list from iterator
+
+convert MTIME structure to uint64_t if possible
+
+investigate why file descriptors can't be directly used in Windows
+
+Fill in and update remaining regfi/pyregfi API documentation
+
+Possible debian package build rules
+
+Testing
+  Full diffs
+  regfi and pyregfi threading
+  valgrind in multiple scenarios for reglookup, reglookup-recover
+
Index: /test/pyregfi-smoketest.py
===================================================================
--- /test/pyregfi-smoketest.py	(revision 231)
+++ /test/pyregfi-smoketest.py	(revision 232)
@@ -10,5 +10,5 @@
 
 
-pyregfi.SetLogMask((pyregfi.LOG_TYPES.INFO, pyregfi.LOG_TYPES.WARN, pyregfi.LOG_TYPES.ERROR))
+pyregfi.setLogMask((pyregfi.LOG_TYPES.INFO, pyregfi.LOG_TYPES.WARN, pyregfi.LOG_TYPES.ERROR))
 
 # Uses the HiveIterator to walk all keys
@@ -262,5 +262,5 @@
         t(hive, fh)
         print("##END %s; runtime=%f; messages:" % (tstr, time.time() - teststart))
-        print(pyregfi.GetLogMessages())
+        print(pyregfi.getLogMessages())
         print
         sys.stdout.flush()
Index: /trunk/SConstruct
===================================================================
--- /trunk/SConstruct	(revision 231)
+++ /trunk/SConstruct	(revision 232)
@@ -1,6 +1,8 @@
 import sys
 import os
+from regfi_version import REGFI_VERSION
 
 cflags = '-std=gnu99 -pedantic -Wall -D_FILE_OFFSET_BITS=64 -fvisibility=hidden'
+cflags += ' -DREGFI_VERSION=\'"%s"\'' % REGFI_VERSION
 cflags += ' -ggdb'
 
Index: /trunk/include/regfi.h
===================================================================
--- /trunk/include/regfi.h	(revision 231)
+++ /trunk/include/regfi.h	(revision 232)
@@ -79,4 +79,9 @@
 #include <range_list.h>
 #include <lru_cache.h>
+
+/* Library version can be overridden at build time */
+#ifndef REGFI_VERSION
+#define REGFI_VERSION "trunk"
+#endif
 
 /* GCC-specific macro for library exports */
Index: /trunk/python/pyregfi/__init__.py
===================================================================
--- /trunk/python/pyregfi/__init__.py	(revision 231)
+++ /trunk/python/pyregfi/__init__.py	(revision 232)
@@ -189,5 +189,5 @@
 # should be reported to the user.  Failure to retrieve these could result in 
 # excessive memory consumption.
-def GetLogMessages():
+def getLogMessages():
     msgs = regfi.regfi_log_get_str()
     if not msgs:
@@ -206,5 +206,5 @@
 # Example:
 # @code
-# SetLogMask((LOG_TYPES.ERROR, LOG_TYPES.WARN, LOG_TYPES.INFO))
+# setLogMask((LOG_TYPES.ERROR, LOG_TYPES.WARN, LOG_TYPES.INFO))
 # @endcode
 #
@@ -212,5 +212,5 @@
 # For more information, see @ref regfi_log_set_mask.
 #
-def SetLogMask(log_types):
+def setLogMask(log_types):
     mask = 0
     for m in log_types:
@@ -219,4 +219,15 @@
 
 
+## Opens a file as a registry hive
+#
+# @param path The file path of a hive, as one would provide to the 
+#             open() built-in
+#
+# @return A new Hive instance
+def openHive(path):
+    fh = open(path, 'rb')
+    return Hive(fh)
+
+
 ## Abstract class for most objects returned by the library
 class _StructureWrapper(object):
@@ -228,9 +239,9 @@
             raise Exception("Could not create _StructureWrapper,"
                             + " hive is NULL.  Current log:\n"
-                            + GetLogMessages())
+                            + getLogMessages())
         if not base:
             raise Exception("Could not create _StructureWrapper,"
                             + " base is NULL.  Current log:\n"
-                            + GetLogMessages())
+                            + getLogMessages())
         self._hive = hive
         self._base = base
@@ -297,9 +308,9 @@
         if not key:
             raise Exception("Could not create _GenericList; key is NULL."
-                            + "Current log:\n" + GetLogMessages())
+                            + "Current log:\n" + getLogMessages())
         
         if not regfi.regfi_reference_record(key._hive.file, key._base):
             raise Exception("Could not create _GenericList; memory error."
-                            + "Current log:\n" + GetLogMessages())
+                            + "Current log:\n" + getLogMessages())
         self._key_base = key._base
         self._length = self._fetch_num(self._key_base)
@@ -650,8 +661,8 @@
     minor_version = 5
 
-    # XXX: Possibly add a second or factory function which opens a 
-    #      hive file for you
-
     ## Constructor
+    #
+    # Initialize a new Hive based on a Python file object.  To open a file by 
+    # path, see @ref openHive.
     #
     # @param fh A Python file object.  The constructor first looks for a valid
@@ -660,5 +671,10 @@
     #           access.
     #
-    # @note Supplied file must be seekable
+    # @note Supplied file must be seekable.  Do not perform any operation on
+    #       the provided file object while a Hive is using it.  Do not 
+    #       construct multiple Hive instances from the same file object.
+    #       If a file must be accessed by separate code and pyregfi 
+    #       simultaneously, use a separate file descriptor.  Hives are 
+    #       thread-safe, so multiple threads may use a single Hive object.
     def __init__(self, fh):
         # The fileno method may not exist, or it may throw an exception
@@ -678,5 +694,5 @@
                 # XXX: switch to non-generic exception
                 raise Exception("Could not open registry file.  Current log:\n"
-                                + GetLogMessages())
+                                + getLogMessages())
         else:
             fh.seek(0)
@@ -689,5 +705,5 @@
                 # XXX: switch to non-generic exception
                 raise Exception("Could not open registry file.  Current log:\n"
-                                + GetLogMessages())
+                                + getLogMessages())
 
 
@@ -753,5 +769,5 @@
         if not self._iter:
             raise Exception("Could not create iterator.  Current log:\n"
-                            + GetLogMessages())
+                            + getLogMessages())
         self._hive = hive
         self._lock = threading.RLock()
@@ -797,5 +813,5 @@
                 self._lock.release()
                 raise Exception('Error traversing iterator downward.'+
-                                ' Current log:\n'+ GetLogMessages())
+                                ' Current log:\n'+ getLogMessages())
 
         regfi.regfi_iterator_first_subkey(self._iter)
@@ -977,5 +993,5 @@
         if not result:
             # XXX: Use non-generic exception
-            raise Exception('Could not locate path.\n'+GetLogMessages())
+            raise Exception('Could not locate path.\n'+getLogMessages())
 
 
Index: /trunk/regfi_version.py
===================================================================
--- /trunk/regfi_version.py	(revision 231)
+++ /trunk/regfi_version.py	(revision 232)
@@ -1,3 +1,2 @@
-
 SVN_REV = "$Rev$"
-REGFI_VERSION = "svn-%s" % SVN_REV.split(' ')[2]
+REGFI_VERSION = "svn-%s" % SVN_REV.split(' ')[1]
Index: /trunk/src/common.c
===================================================================
--- /trunk/src/common.c	(revision 231)
+++ /trunk/src/common.c	(revision 232)
@@ -3,5 +3,5 @@
  * XXX: This should be converted to a proper library.
  *
- * Copyright (C) 2005-2008 Timothy D. Morgan
+ * Copyright (C) 2005-2008,2011 Timothy D. Morgan
  * Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com
  *
@@ -28,6 +28,4 @@
 const char* subfield_special_chars = ",\"\\|";
 const char* common_special_chars = ",\"\\";
-
-#define REGLOOKUP_VERSION "0.1?.0"
 
 #define REGLOOKUP_EXIT_OK       0
Index: /trunk/src/reglookup-recover.c
===================================================================
--- /trunk/src/reglookup-recover.c	(revision 231)
+++ /trunk/src/reglookup-recover.c	(revision 232)
@@ -336,5 +336,5 @@
 {
   fprintf(stderr, "Usage: reglookup-recover [options] <REGISTRY_FILE>\n");
-  fprintf(stderr, "Version: %s\n", REGLOOKUP_VERSION);
+  fprintf(stderr, "Version: %s\n", REGFI_VERSION);
   fprintf(stderr, "Options:\n");
   fprintf(stderr, "\t-v\t sets verbose mode.\n");
Index: /trunk/src/reglookup.c
===================================================================
--- /trunk/src/reglookup.c	(revision 231)
+++ /trunk/src/reglookup.c	(revision 232)
@@ -551,5 +551,5 @@
 	  " [-p <PATH_FILTER>] [-t <TYPE_FILTER>]"
 	  " <REGISTRY_FILE>\n");
-  fprintf(stderr, "Version: %s\n", REGLOOKUP_VERSION);
+  fprintf(stderr, "Version: %s\n", REGFI_VERSION);
   fprintf(stderr, "Options:\n");
   fprintf(stderr, "\t-v\t sets verbose mode.\n");
