gpg: Change parse_packet to take a context.
authorWerner Koch <wk@gnupg.org>
Wed, 29 Mar 2017 08:02:40 +0000 (10:02 +0200)
committerWerner Koch <wk@gnupg.org>
Wed, 29 Mar 2017 08:06:29 +0000 (10:06 +0200)
* g10/packet.h (struct parse_packet_ctx_s): New.
(parse_packet_ctx_t): New type.
(init_parse_packet): New macro.
* g10/parse-packet.c (parse_packet, dbg_parse_packet): Change to take
a parse context.  Change all callers to provide a context instead of
directly supplying the input stream.
(search_packet, dbg_search_packet): Ditto.
(copy_all_packets, dbg_copy_all_packets): Init an use a parse context.
(copy_some_packets, dbg_copy_some_packets): Ditto.
(skip_some_packets, dbg_skip_some_packets): Ditto.
--

We will need this change to handle ring packets inside the parser.

Signed-off-by: Werner Koch <wk@gnupg.org>
g10/import.c
g10/keydb.c
g10/keyedit.c
g10/keyring.c
g10/mainproc.c
g10/packet.h
g10/parse-packet.c

index ea7a92f..9aa6c8b 100644 (file)
@@ -762,6 +762,7 @@ static int
 read_block( IOBUF a, PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys)
 {
   int rc;
 read_block( IOBUF a, PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys)
 {
   int rc;
+  struct parse_packet_ctx_s parsectx;
   PACKET *pkt;
   kbnode_t root = NULL;
   int in_cert, in_v3key;
   PACKET *pkt;
   kbnode_t root = NULL;
   int in_cert, in_v3key;
@@ -779,8 +780,9 @@ read_block( IOBUF a, PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys)
 
   pkt = xmalloc (sizeof *pkt);
   init_packet (pkt);
 
   pkt = xmalloc (sizeof *pkt);
   init_packet (pkt);
+  init_parse_packet (&parsectx, a);
   in_v3key = 0;
   in_v3key = 0;
-  while ((rc=parse_packet(a, pkt)) != -1)
+  while ((rc=parse_packet (&parsectx, pkt)) != -1)
     {
       if (rc && (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY
                  && (pkt->pkttype == PKT_PUBLIC_KEY
     {
       if (rc && (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY
                  && (pkt->pkttype == PKT_PUBLIC_KEY
index 27dacf2..c0bc9f5 100644 (file)
@@ -1156,6 +1156,7 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
                       const u32 *sigstatus, kbnode_t *r_keyblock)
 {
   gpg_error_t err;
                       const u32 *sigstatus, kbnode_t *r_keyblock)
 {
   gpg_error_t err;
+  struct parse_packet_ctx_s parsectx;
   PACKET *pkt;
   kbnode_t keyblock = NULL;
   kbnode_t node, *tail;
   PACKET *pkt;
   kbnode_t keyblock = NULL;
   kbnode_t node, *tail;
@@ -1169,12 +1170,13 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
   if (!pkt)
     return gpg_error_from_syserror ();
   init_packet (pkt);
   if (!pkt)
     return gpg_error_from_syserror ();
   init_packet (pkt);
+  init_parse_packet (&parsectx, iobuf);
   save_mode = set_packet_list_mode (0);
   in_cert = 0;
   n_sigs = 0;
   tail = NULL;
   pk_count = uid_count = 0;
   save_mode = set_packet_list_mode (0);
   in_cert = 0;
   n_sigs = 0;
   tail = NULL;
   pk_count = uid_count = 0;
-  while ((err = parse_packet (iobuf, pkt)) != -1)
+  while ((err = parse_packet (&parsectx, pkt)) != -1)
     {
       if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET)
         {
     {
       if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET)
         {
index 9a7fe13..76d1889 100644 (file)
@@ -2431,6 +2431,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
            char *fname;
            PACKET *pkt;
            IOBUF a;
            char *fname;
            PACKET *pkt;
            IOBUF a;
+            struct parse_packet_ctx_s parsectx;
 
             if (!*arg_string)
              {
 
             if (!*arg_string)
              {
@@ -2464,7 +2465,8 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
            /* Parse and check that file.  */
            pkt = xmalloc (sizeof *pkt);
            init_packet (pkt);
            /* Parse and check that file.  */
            pkt = xmalloc (sizeof *pkt);
            init_packet (pkt);
-           err = parse_packet (a, pkt);
+            init_parse_packet (&parsectx, a);
+           err = parse_packet (&parsectx, pkt);
            iobuf_close (a);
            iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char *) fname);
            if (!err && pkt->pkttype != PKT_SECRET_KEY
            iobuf_close (a);
            iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char *) fname);
            if (!err && pkt->pkttype != PKT_SECRET_KEY
index 31f60f9..e4fc111 100644 (file)
@@ -378,6 +378,7 @@ int
 keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
 {
     PACKET *pkt;
 keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
 {
     PACKET *pkt;
+    struct parse_packet_ctx_s parsectx;
     int rc;
     KBNODE keyblock = NULL, node, lastnode;
     IOBUF a;
     int rc;
     KBNODE keyblock = NULL, node, lastnode;
     IOBUF a;
@@ -407,10 +408,11 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
 
     pkt = xmalloc (sizeof *pkt);
     init_packet (pkt);
 
     pkt = xmalloc (sizeof *pkt);
     init_packet (pkt);
+    init_parse_packet (&parsectx, a);
     hd->found.n_packets = 0;;
     lastnode = NULL;
     save_mode = set_packet_list_mode(0);
     hd->found.n_packets = 0;;
     lastnode = NULL;
     save_mode = set_packet_list_mode(0);
-    while ((rc=parse_packet (a, pkt)) != -1) {
+    while ((rc=parse_packet (&parsectx, pkt)) != -1) {
         hd->found.n_packets++;
         if (gpg_err_code (rc) == GPG_ERR_UNKNOWN_PACKET) {
            free_packet (pkt);
         hd->found.n_packets++;
         if (gpg_err_code (rc) == GPG_ERR_UNKNOWN_PACKET) {
            free_packet (pkt);
@@ -985,6 +987,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
 {
   int rc;
   PACKET pkt;
 {
   int rc;
   PACKET pkt;
+  struct parse_packet_ctx_s parsectx;
   int save_mode;
   off_t offset, main_offset;
   size_t n;
   int save_mode;
   off_t offset, main_offset;
   size_t n;
@@ -1120,12 +1123,13 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
   if (DBG_LOOKUP)
     log_debug ("%s: %ssearching from start of resource.\n",
                __func__, scanned_from_start ? "" : "not ");
   if (DBG_LOOKUP)
     log_debug ("%s: %ssearching from start of resource.\n",
                __func__, scanned_from_start ? "" : "not ");
+  init_parse_packet (&parsectx, hd->current.iobuf);
   while (1)
     {
       byte afp[MAX_FINGERPRINT_LEN];
       size_t an;
 
   while (1)
     {
       byte afp[MAX_FINGERPRINT_LEN];
       size_t an;
 
-      rc = search_packet (hd->current.iobuf, &pkt, &offset, need_uid);
+      rc = search_packet (&parsectx, &pkt, &offset, need_uid);
       if (ignore_legacy && gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
         {
           free_packet (&pkt);
       if (ignore_legacy && gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
         {
           free_packet (&pkt);
index 4c5dce1..30d9b18 100644 (file)
@@ -1330,6 +1330,7 @@ static int
 do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a)
 {
   PACKET *pkt;
 do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a)
 {
   PACKET *pkt;
+  struct parse_packet_ctx_s parsectx;
   int rc = 0;
   int any_data = 0;
   int newpkt;
   int rc = 0;
   int any_data = 0;
   int newpkt;
@@ -1341,7 +1342,8 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a)
   pkt = xmalloc( sizeof *pkt );
   c->iobuf = a;
   init_packet(pkt);
   pkt = xmalloc( sizeof *pkt );
   c->iobuf = a;
   init_packet(pkt);
-  while ((rc=parse_packet(a, pkt)) != -1)
+  init_parse_packet (&parsectx, a);
+  while ((rc=parse_packet (&parsectx, pkt)) != -1)
     {
       any_data = 1;
       if (rc)
     {
       any_data = 1;
       if (rc)
index efccc76..ffa1fe9 100644 (file)
@@ -592,12 +592,26 @@ int list_packets( iobuf_t a );
 */
 int set_packet_list_mode( int mode );
 
 */
 int set_packet_list_mode( int mode );
 
+
+/* A context used with parse_packet.  */
+struct parse_packet_ctx_s
+{
+  iobuf_t inp; /* The input stream with the packets.  */
+};
+typedef struct parse_packet_ctx_s *parse_packet_ctx_t;
+
+#define init_parse_packet(a,i) do { (a)->inp = (i);    \
+    /**/                       } while (0)
+
+
+
 #if DEBUG_PARSE_PACKET
 /* There are debug functions and should not be used directly.  */
 #if DEBUG_PARSE_PACKET
 /* There are debug functions and should not be used directly.  */
-int dbg_search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid,
+int dbg_search_packet (parse_packet_ctx_t ctx, PACKET *pkt,
+                       off_t *retpos, int with_uid,
                        const char* file, int lineno  );
                        const char* file, int lineno  );
-int dbg_parse_packet( iobuf_t inp, PACKET *ret_pkt,
-                      const char* file, int lineno );
+int dbg_parse_packet (parse_packet_ctx_t ctx, PACKET *ret_pkt,
+                      const char *file, int lineno);
 int dbg_copy_all_packets( iobuf_t inp, iobuf_t out,
                           const char* file, int lineno  );
 int dbg_copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff,
 int dbg_copy_all_packets( iobuf_t inp, iobuf_t out,
                           const char* file, int lineno  );
 int dbg_copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff,
@@ -616,51 +630,53 @@ int dbg_skip_some_packets( iobuf_t inp, unsigned n,
              dbg_skip_some_packets((a),(b), __FILE__, __LINE__ )
 #else
 /* Return the next valid OpenPGP packet in *PKT.  (This function will
              dbg_skip_some_packets((a),(b), __FILE__, __LINE__ )
 #else
 /* Return the next valid OpenPGP packet in *PKT.  (This function will
-   skip any packets whose type is 0.)
-
-   Returns 0 on success, -1 if EOF is reached, and an error code
-   otherwise.  In the case of an error, the packet in *PKT may be
-   partially constructed.  As such, even if there is an error, it is
-   necessary to free *PKT to avoid a resource leak.  To detect what
-   has been allocated, clear *PKT before calling this function.  */
-int parse_packet( iobuf_t inp, PACKET *pkt);
+ * skip any packets whose type is 0.)  CTX must have been setup prior to
+ * calling this function.
+ *
+ * Returns 0 on success, -1 if EOF is reached, and an error code
+ * otherwise.  In the case of an error, the packet in *PKT may be
+ * partially constructed.  As such, even if there is an error, it is
+ * necessary to free *PKT to avoid a resource leak.  To detect what
+ * has been allocated, clear *PKT before calling this function.  */
+int parse_packet (parse_packet_ctx_t ctx, PACKET *pkt);
 
 /* Return the first OpenPGP packet in *PKT that contains a key (either
 
 /* Return the first OpenPGP packet in *PKT that contains a key (either
-   a public subkey, a public key, a secret subkey or a secret key) or,
-   if WITH_UID is set, a user id.
-
-   Saves the position in the pipeline of the start of the returned
-   packet (according to iobuf_tell) in RETPOS, if it is not NULL.
-
-   The return semantics are the same as parse_packet.  */
-int search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid );
+ * a public subkey, a public key, a secret subkey or a secret key) or,
+ * if WITH_UID is set, a user id.
+ *
+ * Saves the position in the pipeline of the start of the returned
+ * packet (according to iobuf_tell) in RETPOS, if it is not NULL.
+ *
+ * The return semantics are the same as parse_packet.  */
+int search_packet (parse_packet_ctx_t ctx, PACKET *pkt,
+                   off_t *retpos, int with_uid);
 
 /* Copy all packets (except invalid packets, i.e., those with a type
 
 /* Copy all packets (except invalid packets, i.e., those with a type
  of 0) from INP to OUT until either an error occurs or EOF is
  reached.
-
  Returns -1 when end of file is reached or an error code, if an
  error occurred.  (Note: this function never returns 0, because it
  effectively keeps going until it gets an EOF.)  */
-int copy_all_packetsiobuf_t inp, iobuf_t out );
* of 0) from INP to OUT until either an error occurs or EOF is
* reached.
+ *
* Returns -1 when end of file is reached or an error code, if an
* error occurred.  (Note: this function never returns 0, because it
* effectively keeps going until it gets an EOF.)  */
+int copy_all_packets (iobuf_t inp, iobuf_t out );
 
 /* Like copy_all_packets, but stops at the first packet that starts at
 
 /* Like copy_all_packets, but stops at the first packet that starts at
  or after STOPOFF (as indicated by iobuf_tell).
-
-   Example: if STOPOFF is 100, the first packet in INP goes from 0 to
  110 and the next packet starts at offset 111, then the packet
  starting at offset 0 will be completely processed (even though it
  extends beyond STOPOFF) and the packet starting at offset 111 will
  not be processed at all.  */
-int copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff );
* or after STOPOFF (as indicated by iobuf_tell).
+ *
+ * Example: if STOPOFF is 100, the first packet in INP goes from
* 0 to 110 and the next packet starts at offset 111, then the packet
* starting at offset 0 will be completely processed (even though it
* extends beyond STOPOFF) and the packet starting at offset 111 will
* not be processed at all.  */
+int copy_some_packets (iobuf_t inp, iobuf_t out, off_t stopoff);
 
 /* Skips the next N packets from INP.
 
 /* Skips the next N packets from INP.
-
  If parsing a packet returns an error code, then the function stops
  immediately and returns the error code.  Note: in the case of an
  error, this function does not indicate how many packets were
  successfully processed.  */
-int skip_some_packets( iobuf_t inp, unsigned n );
+ *
* If parsing a packet returns an error code, then the function stops
* immediately and returns the error code.  Note: in the case of an
* error, this function does not indicate how many packets were
* successfully processed.  */
+int skip_some_packets (iobuf_t inp, unsigned int n);
 #endif
 
 /* Parse a signature packet and store it in *SIG.
 #endif
 
 /* Parse a signature packet and store it in *SIG.
index 06b286b..7766a45 100644 (file)
@@ -48,7 +48,7 @@ static int mpi_print_mode;
 static int list_mode;
 static estream_t listfp;
 
 static int list_mode;
 static estream_t listfp;
 
-static int parse (IOBUF inp, PACKET * pkt, int onlykeypkts,
+static int parse (parse_packet_ctx_t ctx, PACKET *pkt, int onlykeypkts,
                  off_t * retpos, int *skip, IOBUF out, int do_skip
 #ifdef DEBUG_PARSE_PACKET
                  , const char *dbg_w, const char *dbg_f, int dbg_l
                  off_t * retpos, int *skip, IOBUF out, int do_skip
 #ifdef DEBUG_PARSE_PACKET
                  , const char *dbg_w, const char *dbg_f, int dbg_l
@@ -263,26 +263,27 @@ unknown_pubkey_warning (int algo)
 
 #ifdef DEBUG_PARSE_PACKET
 int
 
 #ifdef DEBUG_PARSE_PACKET
 int
-dbg_parse_packet (IOBUF inp, PACKET *pkt, const char *dbg_f, int dbg_l)
+dbg_parse_packet (parse_packet_ctx_t ctx, PACKET *pkt,
+                  const char *dbg_f, int dbg_l)
 {
   int skip, rc;
 
   do
     {
 {
   int skip, rc;
 
   do
     {
-      rc = parse (inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l);
+      rc = parse (ctx, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l);
     }
   while (skip && ! rc);
   return rc;
 }
 #else /*!DEBUG_PARSE_PACKET*/
 int
     }
   while (skip && ! rc);
   return rc;
 }
 #else /*!DEBUG_PARSE_PACKET*/
 int
-parse_packet (IOBUF inp, PACKET * pkt)
+parse_packet (parse_packet_ctx_t ctx, PACKET *pkt)
 {
   int skip, rc;
 
   do
     {
 {
   int skip, rc;
 
   do
     {
-      rc = parse (inp, pkt, 0, NULL, &skip, NULL, 0);
+      rc = parse (ctx, pkt, 0, NULL, &skip, NULL, 0);
     }
   while (skip && ! rc);
   return rc;
     }
   while (skip && ! rc);
   return rc;
@@ -296,29 +297,30 @@ parse_packet (IOBUF inp, PACKET * pkt)
  */
 #ifdef DEBUG_PARSE_PACKET
 int
  */
 #ifdef DEBUG_PARSE_PACKET
 int
-dbg_search_packet (IOBUF inp, PACKET * pkt, off_t * retpos, int with_uid,
+dbg_search_packet (parse_packet_ctx_t ctx, PACKET *pkt,
+                   off_t * retpos, int with_uid,
                   const char *dbg_f, int dbg_l)
 {
   int skip, rc;
 
   do
     {
                   const char *dbg_f, int dbg_l)
 {
   int skip, rc;
 
   do
     {
-      rc =
-       parse (inp, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0, "search",
-              dbg_f, dbg_l);
+      rc = parse (ctx, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0, "search",
+                  dbg_f, dbg_l);
     }
   while (skip && ! rc);
   return rc;
 }
 #else /*!DEBUG_PARSE_PACKET*/
 int
     }
   while (skip && ! rc);
   return rc;
 }
 #else /*!DEBUG_PARSE_PACKET*/
 int
-search_packet (IOBUF inp, PACKET * pkt, off_t * retpos, int with_uid)
+search_packet (parse_packet_ctx_t ctx, PACKET *pkt,
+               off_t * retpos, int with_uid)
 {
   int skip, rc;
 
   do
     {
 {
   int skip, rc;
 
   do
     {
-      rc = parse (inp, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0);
+      rc = parse (ctx, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0);
     }
   while (skip && ! rc);
   return rc;
     }
   while (skip && ! rc);
   return rc;
@@ -331,38 +333,45 @@ search_packet (IOBUF inp, PACKET * pkt, off_t * retpos, int with_uid)
  */
 #ifdef DEBUG_PARSE_PACKET
 int
  */
 #ifdef DEBUG_PARSE_PACKET
 int
-dbg_copy_all_packets (IOBUF inp, IOBUF out, const char *dbg_f, int dbg_l)
+dbg_copy_all_packets (iobuf_t inp, iobuf_t out, const char *dbg_f, int dbg_l)
 {
   PACKET pkt;
 {
   PACKET pkt;
+  struct parse_packet_ctx_s parsectx;
   int skip, rc = 0;
 
   if (! out)
     log_bug ("copy_all_packets: OUT may not be NULL.\n");
 
   int skip, rc = 0;
 
   if (! out)
     log_bug ("copy_all_packets: OUT may not be NULL.\n");
 
+  init_parse_packet (&parsectx, inp);
+
   do
     {
       init_packet (&pkt);
     }
   while (!
         (rc =
   do
     {
       init_packet (&pkt);
     }
   while (!
         (rc =
-         parse (inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l)));
+         parse (&parsectx, &pkt, 0, NULL, &skip, out, 0, "copy",
+                 dbg_f, dbg_l)));
   return rc;
 }
 #else /*!DEBUG_PARSE_PACKET*/
 int
   return rc;
 }
 #else /*!DEBUG_PARSE_PACKET*/
 int
-copy_all_packets (IOBUF inp, IOBUF out)
+copy_all_packets (iobuf_t inp, iobuf_t out)
 {
   PACKET pkt;
 {
   PACKET pkt;
+  struct parse_packet_ctx_s parsectx;
   int skip, rc = 0;
 
   if (! out)
     log_bug ("copy_all_packets: OUT may not be NULL.\n");
 
   int skip, rc = 0;
 
   if (! out)
     log_bug ("copy_all_packets: OUT may not be NULL.\n");
 
+  init_parse_packet (&parsectx, inp);
+
   do
     {
       init_packet (&pkt);
     }
   do
     {
       init_packet (&pkt);
     }
-  while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0)));
+  while (!(rc = parse (&parsectx, &pkt, 0, NULL, &skip, out, 0)));
   return rc;
 }
 #endif /*!DEBUG_PARSE_PACKET*/
   return rc;
 }
 #endif /*!DEBUG_PARSE_PACKET*/
@@ -375,34 +384,44 @@ copy_all_packets (IOBUF inp, IOBUF out)
  */
 #ifdef DEBUG_PARSE_PACKET
 int
  */
 #ifdef DEBUG_PARSE_PACKET
 int
-dbg_copy_some_packets (IOBUF inp, IOBUF out, off_t stopoff,
+dbg_copy_some_packets (iobuf_t inp, iobuf_t out, off_t stopoff,
                       const char *dbg_f, int dbg_l)
 {
                       const char *dbg_f, int dbg_l)
 {
+  int rc = 0;
   PACKET pkt;
   PACKET pkt;
-  int skip, rc = 0;
+  int skip;
+  struct parse_packet_ctx_s parsectx;
+
+  init_parse_packet (&parsectx, inp);
+
   do
     {
       if (iobuf_tell (inp) >= stopoff)
        return 0;
       init_packet (&pkt);
     }
   do
     {
       if (iobuf_tell (inp) >= stopoff)
        return 0;
       init_packet (&pkt);
     }
-  while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0,
+  while (!(rc = parse (&parsectx, &pkt, 0, NULL, &skip, out, 0,
                       "some", dbg_f, dbg_l)));
   return rc;
 }
 #else /*!DEBUG_PARSE_PACKET*/
 int
                       "some", dbg_f, dbg_l)));
   return rc;
 }
 #else /*!DEBUG_PARSE_PACKET*/
 int
-copy_some_packets (IOBUF inp, IOBUF out, off_t stopoff)
+copy_some_packets (iobuf_t inp, iobuf_t out, off_t stopoff)
 {
 {
+  int rc = 0;
   PACKET pkt;
   PACKET pkt;
-  int skip, rc = 0;
+  struct parse_packet_ctx_s parsectx;
+  int skip;
+
+  init_parse_packet (&parsectx, inp);
+
   do
     {
       if (iobuf_tell (inp) >= stopoff)
        return 0;
       init_packet (&pkt);
     }
   do
     {
       if (iobuf_tell (inp) >= stopoff)
        return 0;
       init_packet (&pkt);
     }
-  while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0)));
+  while (!(rc = parse (&parsectx, &pkt, 0, NULL, &skip, out, 0)));
   return rc;
 }
 #endif /*!DEBUG_PARSE_PACKET*/
   return rc;
 }
 #endif /*!DEBUG_PARSE_PACKET*/
@@ -413,29 +432,38 @@ copy_some_packets (IOBUF inp, IOBUF out, off_t stopoff)
  */
 #ifdef DEBUG_PARSE_PACKET
 int
  */
 #ifdef DEBUG_PARSE_PACKET
 int
-dbg_skip_some_packets (IOBUF inp, unsigned n, const char *dbg_f, int dbg_l)
+dbg_skip_some_packets (iobuf_t inp, unsigned n, const char *dbg_f, int dbg_l)
 {
 {
-  int skip, rc = 0;
+  int rc = 0;
+  int skip;
   PACKET pkt;
   PACKET pkt;
+  struct parse_packet_ctx_s parsectx;
+
+  init_parse_packet (&parsectx, inp);
 
   for (; n && !rc; n--)
     {
       init_packet (&pkt);
 
   for (; n && !rc; n--)
     {
       init_packet (&pkt);
-      rc = parse (inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l);
+      rc = parse (&parsectx, &pkt, 0, NULL, &skip, NULL, 1, "skip",
+                  dbg_f, dbg_l);
     }
   return rc;
 }
 #else /*!DEBUG_PARSE_PACKET*/
 int
     }
   return rc;
 }
 #else /*!DEBUG_PARSE_PACKET*/
 int
-skip_some_packets (IOBUF inp, unsigned n)
+skip_some_packets (iobuf_t inp, unsigned int n)
 {
 {
-  int skip, rc = 0;
+  int rc = 0;
+  int skip;
   PACKET pkt;
   PACKET pkt;
+  struct parse_packet_ctx_s parsectx;
+
+  init_parse_packet (&parsectx, inp);
 
   for (; n && !rc; n--)
     {
       init_packet (&pkt);
 
   for (; n && !rc; n--)
     {
       init_packet (&pkt);
-      rc = parse (inp, &pkt, 0, NULL, &skip, NULL, 1);
+      rc = parse (&parsectx, &pkt, 0, NULL, &skip, NULL, 1);
     }
   return rc;
 }
     }
   return rc;
 }
@@ -466,18 +494,20 @@ skip_some_packets (IOBUF inp, unsigned n)
    Note: ONLYKEYPKTS and DO_SKIP are only respected if OUT is NULL,
    i.e., the packets are not simply being copied.
 
    Note: ONLYKEYPKTS and DO_SKIP are only respected if OUT is NULL,
    i.e., the packets are not simply being copied.
 
-   If RETPOS is not NULL, then the position of INP (as returned by
-   iobuf_tell) is saved there before any data is read from INP.
+   If RETPOS is not NULL, then the position of CTX->INP (as returned by
+   iobuf_tell) is saved there before any data is read from CTX->INP.
   */
 static int
   */
 static int
-parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos,
+parse (parse_packet_ctx_t ctx, PACKET *pkt, int onlykeypkts, off_t * retpos,
        int *skip, IOBUF out, int do_skip
 #ifdef DEBUG_PARSE_PACKET
        , const char *dbg_w, const char *dbg_f, int dbg_l
 #endif
        )
 {
        int *skip, IOBUF out, int do_skip
 #ifdef DEBUG_PARSE_PACKET
        , const char *dbg_w, const char *dbg_f, int dbg_l
 #endif
        )
 {
-  int rc = 0, c, ctb, pkttype, lenbytes;
+  int rc = 0;
+  iobuf_t inp;
+  int c, ctb, pkttype, lenbytes;
   unsigned long pktlen;
   byte hdr[8];
   int hdrlen;
   unsigned long pktlen;
   byte hdr[8];
   int hdrlen;
@@ -486,6 +516,8 @@ parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos,
   off_t pos;
 
   *skip = 0;
   off_t pos;
 
   *skip = 0;
+  inp = ctx->inp;
+
   log_assert (!pkt->pkt.generic);
   if (retpos || list_mode)
     {
   log_assert (!pkt->pkt.generic);
   if (retpos || list_mode)
     {