Index: misc/client.py
===================================================================
--- misc/client.py	(revision 7)
+++ misc/client.py	(revision 8)
@@ -39,4 +39,43 @@
 
     @staticmethod
+    def _parseGetSpec(words):
+        """Parse a data query specification from the given argument word lisst.
+
+        If there is some failure, it returns None.
+
+        Otherwise it returns a tuple of two items:
+        - the parsed data, which is a tuple of these items:
+          - the name of the dataref to query
+          - the type of the dataref to query (it is a valid type, checked by
+          the function)
+          - the length of the dataref to query
+          - the offset to query the dataref from
+
+        - the remainder of the argument list."""
+        if len(words)<2:
+            print >> sys.stderr, "Missing parameters"
+            return None
+
+        nextIndex = 2
+
+        name = words[0]
+        type = words[1]
+        if type not in CLI._types:
+            print >> sys.stderr, "Invalid type"
+            return None
+
+        length = None
+        offset = None
+        if type in ["ia", "fa", "ba", "s"]:
+            if len(words)<4:
+                print >> sys.stderr, "Missing parameters"
+                return None
+            length = int(words[2])
+            offset = int(words[3])
+            nextIndex = 4
+
+        return ((name, type, length, offset), words[nextIndex:])
+
+    @staticmethod
     def _packLength(x):
         """Pack the given integer as a variable-length value."""
@@ -60,4 +99,5 @@
 
         self._stream = stream
+        self._multiGets = {}
 
         self.use_rawinput = True
@@ -78,20 +118,9 @@
         """Handle the 'get' command"""
         words = self._splitArgs(args)
-        if len(words)<2:
-            print >> sys.stderr, "Missing parameters"
-            return False
-
-        name = words[0]
-
-        type = words[1]
-        if type not in self._types:
-            print >> sys.stderr, "Invalid type"
-            return False
-
-        length = None
-        offset = None
-        if len(words)>3:
-            length = int(words[2])
-            offset = int(words[3])
+        result = self._parseGetSpec(words)
+        if result is None:
+            return False
+
+        (name, type, length, offset) = result[0]
 
         self._writeU8(0x01)
@@ -107,5 +136,5 @@
             print self._readValue(type)
         else:
-            print "Error code:", result
+            print >> sys.stderr, "Error code:", result
 
     def do_set(self, args):
@@ -143,5 +172,87 @@
         result = self._readU8()
         if result!=0:
-            print "Error code:", result
+            print >> sys.stderr, "Error code:", result
+
+    def do_reg_multiget(self, args):
+        """Handle the 'reg_multiget' command"""
+        words = self._splitArgs(args)
+        specs = []
+        while words:
+            result = self._parseGetSpec(words)
+            if result is None:
+                return False
+            else:
+                specs.append(result[0])
+                words = result[1]
+
+        if not specs:
+            return False
+
+        self._writeU8(0x11)
+        self._writeU32(len(specs))
+        for (name, type, length, offset) in specs:
+            print name, type
+            self._writeString(name)
+            self._writeU8(self._types[type])
+            if length is not None:
+                self._writeS32(length)
+                self._writeS32(offset)
+        self._flush()
+
+        result = self._readU8()
+        if result==0:
+            id = self._readU32()
+            self._multiGets[id] = \
+                [type for (name, type, length, offset) in specs]
+            print "ID:", id
+        else:
+            print >> sys.stderr, "Error code:", result
+
+    def do_unreg_multiget(self, args):
+        """Handle the 'unreg_multiget' command"""
+        words = self._splitArgs(args)
+        if len(words)<1:
+            print >> sys.stderr, "Missing parameter"
+            return False
+
+        id = int(words[0])
+
+        self._writeU8(0x12)
+        self._writeU32(id)
+        self._flush()
+
+        result = self._readU8()
+        if result!=0:
+            print >> sys.stderr, "Error code:", result
+
+        if id in self._multiGets:
+            del self._multiGets[id]
+
+    def do_exec_multiget(self, args):
+        """Handle the 'unreg_multiget' command"""
+        words = self._splitArgs(args)
+        if len(words)<1:
+            print >> sys.stderr, "Missing parameter"
+            return False
+
+        id = int(words[0])
+        if id not in self._multiGets:
+            print >> sys.stderr, "Invalid ID"
+            return False
+
+        self._writeU8(0x13)
+        self._writeU32(id)
+        self._flush()
+
+        result = self._readU8()
+        if result==0:
+            for type in self._multiGets[id]:
+                value = self._readValue(type)
+                print value
+        elif result==0x02:
+            index = self._readU32()
+            print >> sys.stderr, "Invalid dataref at #%d" % (index,)
+        else:
+            print >> sys.stderr, "Error code:", result
 
     def _writeU8(self, x):
@@ -153,4 +264,8 @@
         self._stream.write(struct.pack("i", x))
 
+    def _writeU32(self, x):
+        """Write the given value as an unsigned, 32-bit value."""
+        self._stream.write(struct.pack("I", x))
+
     def _writeFloat(self, x):
         """Write the given value as a single-precision floating point."""
@@ -181,4 +296,9 @@
         """Read a signed, 32-bit value from the stream."""
         (value,) = struct.unpack("i", self._stream.read(4))
+        return value
+
+    def _readU32(self):
+        """Read an unsigned, 32-bit value from the stream."""
+        (value,) = struct.unpack("I", self._stream.read(4))
         return value
 
Index: misc/test3.sh
===================================================================
--- misc/test3.sh	(revision 8)
+++ misc/test3.sh	(revision 8)
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+scriptdir=`dirname $0`
+
+"${scriptdir}/client.py" <<EOF
+reg_multiget sim/aircraft/engine/acf_num_engines i sim/aircraft/engine/acf_auto_featherEQ i sim/aircraft/engine/acf_spooltime_jet f sim/aircraft/engine/acf_spooltime_prop f sim/flightmodel/position/latitude d sim/flightmodel/position/longitude d sim/aircraft/view/acf_descrip s -1 0 sim/aircraft/prop/acf_en_type ia -1 0 sim/aircraft/prop/acf_prop_dir fa -1 0
+exec_multiget 2
+exec_multiget 1
+unreg_multiget 2
+unreg_multiget 1
+exec_multiget 1
+EOF
