Beispiel #1
0
static void
handle_vmsg_dummy(const struct gnutella_header *header,
  const char *data, size_t size)
{
  (void) header;
  handle_extension(&data[8], size - 8);
}
Beispiel #2
0
static void
handle_vmsg_time_sync_reply(const struct gnutella_header *header,
    const char *data, size_t size)
{
  if (size < 17) {
    printf("Too short:  %s\n", escape_buffer(data, size));
  } else {
    bool used_ntp = data[8] & 0x1;
    char buf[32], *p;

    printf("NTP: %s\n", used_ntp ? "yes" : "no");

    p = print_iso8601_date(buf, sizeof buf, peek_be32(&header->guid.data[0]));
    *p = '\0';
    printf("T1: %s (%lu us)\n",
      buf, (unsigned long) peek_be32(&header->guid.data[4]));

    p = print_iso8601_date(buf, sizeof buf, peek_be32(&data[9]));
    *p = '\0';
    printf("T2: %s (%lu us)\n",
      buf, (unsigned long) peek_be32(&data[13]));

    p = print_iso8601_date(buf, sizeof buf, peek_be32(&header->guid.data[8]));
    *p = '\0';
    printf("T3: %s (%lu us)\n",
      buf, (unsigned long) peek_be32(&header->guid.data[12]));

    if (size > 17) {
      handle_extension(&data[17], size - 17);
    }
  }
}
Beispiel #3
0
static void
handle_vmsg_port(const struct gnutella_header *header,
  const char *data, size_t size)
{
  const char *base = &data[8];
  const size_t len = size - 8;
  (void) header;
  if (len == 2) {
    printf("Port: %u\n", peek_le16(base));
  } else {
    handle_extension(base, len);
  }
}
Beispiel #4
0
static void
handle_vmsg_addr_port(const struct gnutella_header *header,
  const char *data, size_t size)
{
  const char *base = &data[8];
  const size_t len = size - 8;
  (void) header;
  if (len == 6) {
    printf("Address: %s\n", net_addr_port_to_string(
            net_addr_peek_ipv4(&base[0]), peek_le16(&base[4])));
  } else {
    handle_extension(base, len);
  }
}
Beispiel #5
0
static void
handle_vmsg_oob_reply(const struct gnutella_header *header,
  const char *data, size_t size)
{
  (void) header;

  if (size < 9) {
    printf("Too short:  %s\n", escape_buffer(data, size));
  } else {
    printf("Hits: %u\n", (uint8_t) data[8]);
    if (size > 9) {
      handle_extension(&data[9], size - 9);
    }
  }
}
Beispiel #6
0
static void
handle_pong(const char * const data, const size_t size)
{
  if (size < 14) {
    printf("Too short:  %s\n", escape_buffer(data, size));
  } else {
    printf("Source: %s\n",
      net_addr_port_to_string(net_addr_peek_ipv4(&data[2]), peek_le16(data)));
    printf("Files:  %lu\n", (unsigned long) peek_le32(&data[6]));
    printf("Volume: %lu KiB\n", (unsigned long) peek_le32(&data[10]));

    if (size > 14) {
      handle_extension(&data[14], size - 14);
    }
  }
}
Beispiel #7
0
static void
handle_vmsg_time_sync_request(const struct gnutella_header *header,
  const char *data, size_t size)
{
  (void) header;

  if (size < 9) {
    printf("Too short:  %s\n", escape_buffer(data, size));
  } else {
    bool used_ntp = data[8] & 0x1;

    printf("NTP: %s\n", used_ntp ? "yes" : "no");

    if (size > 9) {
      handle_extension(&data[9], size - 9);
    }
  }
}
Beispiel #8
0
static void
handle_push(const char *data, size_t size)
{
  if (size < 26) {
    fprintf(stderr, "handle_push(): Too small\n");
    return;
  }
  printf("ServentID: %08lx-%08lx-%08lx-%08lx\n",
      (unsigned long) peek_be32(&data[0]),
      (unsigned long) peek_be32(&data[4]),
      (unsigned long) peek_be32(&data[8]),
      (unsigned long) peek_be32(&data[12]));
  printf("Index: %lu\n", (unsigned long) peek_le32(&data[16]));
  printf("Target: %s\n",
      net_addr_port_to_string(net_addr_peek_ipv4(&data[20]),
        peek_le16(&data[24])));

  handle_extension(&data[26], size - 26);
}
Beispiel #9
0
static void
handle_vmsg_priv(const struct gnutella_header *header,
    const char *data, size_t size)
{
  if (size < 8) {
    printf("Too short:  %s\n", escape_buffer(data, size));
  } else {
    char vendor[32], *p;
    size_t vendor_size = sizeof vendor;
    struct vmsg_head vh;
    unsigned i;

    p = append_escaped_chars(vendor, &vendor_size, data, 4);
    *p = '\0';

    vh.vendor = peek_be32(&data[0]);
    vh.selector = peek_le16(&data[4]);
    vh.version = peek_le16(&data[6]);
    printf("%s/%uv%u", vendor, vh.selector, vh.version);

    for (i = 0; i < ARRAY_LEN(vmsg_table); i++) {
      if (
        vmsg_table[i].vendor == vh.vendor &&
        vmsg_table[i].selector == vh.selector &&
        vmsg_table[i].version == vh.version
      ) {
        printf(" %s\n", vmsg_table[i].name);
        vmsg_table[i].handler(header, data, size);
        break;
      }
    }

    if (ARRAY_LEN(vmsg_table) == i) {
      printf("\n");
      handle_extension(&data[8], size - 8);
    }
  }
}
Beispiel #10
0
static void
handle_options(int argc, char *argv[], Font *fnt)
{
  register int lastext;
  register int i;
  size_t l;
  int arginc;
  char *temp;
  char c;
  char *vpl_name = NULL;
  Boolean have_capheight = 0;
  Boolean have_sfd = 0;
  int sfd_begin, postfix_begin;
  int base_name;
  stringlist* sl;


  /* scan first whether the -q switch is set */
  for (i = 1; i < argc; i++)
    if (argv[i][0] == '-' && argv[i][1] == 'q')
      quiet = True;

  if (!quiet)
    printf("This is %s\n", ident);

  /* Make VPL file identical to that created under Unix */
  fnt->titlebuf = (char *)mymalloc(strlen(progname) + strlen(argv[1]) +
                                   1 + 1);
  sprintf(fnt->titlebuf, "%s %s", progname, argv[1]);


  /*
   *   TrueType font name.
   */

  fnt->ttfname = newstring(argv[1]);

  /*
   *   The other arguments.  We delay the final processing of some switches
   *   until the tfm font name has been scanned -- if it contains two `@'s,
   *   many switches are ignored.
   */

  while (argc > 2 && *argv[2] == '-')
  {
    arginc = 2;
    i = argv[2][1];

    switch (i)
    {
    case 'v':
      makevpl = 1;
      if (argc <= 3)
        oops("Missing parameter for -v option.");
      if (vpl_name)
        free(vpl_name);
      vpl_name = newstring(argv[3]);
      handle_extension(&vpl_name, ".vpl");
      break;

    case 'V':
      makevpl = 2;
      if (argc <= 3)
        oops("Missing parameter for -V option.");
      if (vpl_name)
        free(vpl_name);
      vpl_name = newstring(argv[3]);
      handle_extension(&vpl_name, ".vpl");
      break;

    case 'f':
      if (argc <= 3)
        oops("Missing parameter for -f option.");
      if (sscanf(argv[3], "%lu", &(fnt->fontindex)) == 0)
        oops("Invalid font index.");
      fnt->fontindexparam = argv[3];
      break;

    case 'E':
      if (argc <= 3)
        oops("Missing parameter for -E option.");
      if (sscanf(argv[3], "%hu", &(fnt->eid)) == 0)
        oops("Invalid encoding ID.");
      fnt->eidparam = argv[3];
      break;

    case 'P':
      if (argc <= 3)
        oops("Missing parameter for -P option.");
      if (sscanf(argv[3], "%hu", &(fnt->pid)) == 0)
        oops("Invalid platform ID.");
      fnt->pidparam = argv[3];
      break;

    case 'e':
      if (argc <= 3)
        oops("Missing parameter for -e option.");
      if (sscanf(argv[3], "%f", &(fnt->efactor)) == 0 || fnt->efactor < 0.01)
        oops("Bad extension factor.");
      fnt->efactorparam = argv[3];
      break;

    case 'c':
      if (argc <= 3)
        oops("Missing parameter for -c option.");
      have_capheight = True;
      if (sscanf(argv[3], "%f", &(fnt->capheight)) == 0)
        fnt->capheight = 0;
      break;

    case 's':
      if (argc <= 3)
        oops("Missing parameter for -s option.");
      if (sscanf(argv[3], "%f", &(fnt->slant)) == 0)
        oops("Bad slant parameter.");
      fnt->slantparam = argv[3];
      break;

    case 'p':
      if (argc <= 3)
        oops("Missing parameter for -p option.");
      if (fnt->inencname)
        free(fnt->inencname);
      fnt->inencname = newstring(argv[3]);
      break;

    case 'T':
      if (argc <= 3)
        oops("Missing parameter for -T option.");
      if (fnt->inencname)
        free(fnt->inencname);
      if (fnt->outencname)
        free(fnt->outencname);
      fnt->inencname = newstring(argv[3]);
      fnt->outencname = newstring(argv[3]);
      break;

    case 't':
      if (argc <= 3)
        oops("Missing parameter for -T option.");
      if (fnt->outencname)
        free(fnt->outencname);
      fnt->outencname = newstring(argv[3]);
      break;

    case 'r':
      if (argc <= 4)
        oops("Not enough parameters for -r option.");
      sl = newstringlist();
      sl->old_name = newstring(argv[3]);
      sl->new_name = newstring(argv[4]);
      sl->single_replacement = True;
      sl->next = fnt->replacements;
      fnt->replacements = sl;
      arginc = 3;
      break;

    case 'R':
      if (argc <= 3)
        oops("Missing parameter for -R option.");
      if (fnt->replacementname)
        free(fnt->replacementname);
      fnt->replacementname = newstring(argv[3]);
      break;

    case 'y':
      if (argc <= 3)
        oops("Missing parameter for -y option.");
      if (sscanf(argv[3], "%f", &(fnt->y_offset)) == 0)
        oops("Invalid y-offset.");
      fnt->y_offsetparam = argv[3];
      break;

    case 'O':
      forceoctal = True;
      arginc = 1;
      break;

    case 'n':
      fnt->PSnames = Yes;
      arginc = 1;
      break;

    case 'N':
      fnt->PSnames = Only;
      arginc = 1;
      break;

    case 'u':
      pedantic = True;
      arginc = 1;
      break;

    case 'q':
      quiet = True;
      arginc = 1;
      break;

    case 'L':
      if (argc <= 3)
        oops("Missing parameter for -L option.");
      if (fnt->ligname)
        free(fnt->ligname);
      fnt->ligname = newstring(argv[3]);
      fnt->subfont_ligs = True;
      break;

    case 'l':
      fnt->subfont_ligs = True;
      arginc = 1;
      break;

    case 'w':
      fnt->write_enc = True;
      arginc = 1;
      break;

    case 'x':
      fnt->rotate = True;
      arginc = 1;
      break;

    case 'o':
      if (argc <= 3)
        oops("Missing parameter for -o option.");
      if (vpl_name)
        free(vpl_name);
      vpl_name = newstring(argv[3]);
      handle_extension(&vpl_name, ".ovp");
      break;

    default:
      if (argc <= 3 || argv[3][0] == '-')
      {
        warning("Unknown option `%s' will be ignored.\n", argv[2]);
        arginc = 1;
      }
      else
        warning("Unknown option `%s %s' will be ignored.\n",
                argv[2], argv[3]);
    }

    for (i = 0; i < arginc; i++)
    {
      l = strlen(fnt->titlebuf);
      fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf,
                                        l + strlen(argv[2]) + 1 + 1);
      sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]);
      argv++;
      argc--;
    }
  }

  /* Read replacement glyph name file */

  get_replacements(fnt);

  if (argc > 3 || (argc == 3 && *argv[2] == '-'))
    oops("Need at most two non-option arguments.");

  /*
   *   The tfm file name.
   */

  if (argc == 2)
    temp = newstring(fnt->ttfname);
  else
  {
    temp = newstring(argv[2]);
    l = strlen(fnt->titlebuf);
    fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf,
                                      l + strlen(argv[2]) + 1 + 1);
    sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]);
  }

  handle_sfd(temp, &sfd_begin, &postfix_begin);

  if (sfd_begin > -1)
  {
    have_sfd = True;
    i = sfd_begin - 2;
  }
  else
    i = strlen(temp) - 1;

  /*
   *   Now we search the beginning of the name without directory.
   */

  for (; i >= 0; i--)
    if (temp[i] == '/' || temp[i] == ':' || temp[i] == '\\')
      break;

  base_name = i + 1;

  /*
   *   We store the path (with the final directory separator).
   */

  if (base_name > 0)
  {
    c = temp[base_name];
    temp[base_name] = '\0';
    fnt->tfm_path = newstring(temp);
    temp[base_name] = c;
  }

  if (have_sfd)
  {
    /* the prefix and the sfd file name */

    if (temp[base_name])
      fnt->outname = newstring(temp + base_name);

    fnt->sfdname = newstring(temp + sfd_begin);
  }
  else
    postfix_begin = base_name;

  /*
   *   Get the extension.
   */

  lastext = -1;
  for (i = postfix_begin; temp[i]; i++)
    if (temp[i] == '.')
      lastext = i;

  if (argc == 2 && lastext >= 0)
  {
    temp[lastext] = '\0';       /* remove TTF file extension */
    lastext = -1;
  }

  if (lastext == -1)
    fnt->tfm_ext = newstring(".tfm");
  else
  {
    fnt->tfm_ext = newstring(temp + lastext);
    temp[lastext] = '\0';
  }

  if (have_sfd)
  {
    if (temp[postfix_begin])
      fnt->outname_postfix = newstring(temp + postfix_begin);
  }
  else
  {
    if (temp[base_name])
      fnt->outname = newstring(temp + base_name);
    else
      oops("Invalid tfm file name.");
  }


  /*
   *   Now we can process the remaining parameters.
   */

  if (have_sfd)
  {
    if (makevpl)
    {
      warning("Ignoring `-v' and `-V' switches for subfonts.");
      makevpl = 0;
    }
    if (vpl_name)
      if ((fnt->vplout = fopen(vpl_name, "wb")) == NULL)
        oops("Cannot open ovp output file.");
    if (have_capheight)
      warning("Ignoring `-c' switch for subfonts.");
    if (fnt->inencname || fnt->outencname)
    {
      warning("Ignoring `-p', `-t', and `-T' switches for subfonts.");
      fnt->inencname = NULL;
      fnt->outencname = NULL;
    }
    if (fnt->y_offsetparam && !fnt->rotate)
      warning("Ignoring `-y' switch for non-rotated subfonts.");
    if (fnt->PSnames)
    {
      warning("Ignoring `-n' or '-N' switch for subfonts.");
      fnt->PSnames = No;
    }

    init_sfd(fnt, True);
  }
  else
  {
    if (have_capheight && fnt->capheight < 0.01)
      oops("Bad small caps height.");

    if (vpl_name)
      if ((fnt->vplout = fopen(vpl_name, "wb")) == NULL)
        oops("Cannot open vpl output file.");
  
    if (fnt->subfont_ligs)
    {
      warning("Ignoring `-l' switch for non-subfont.");
      fnt->subfont_ligs = False;
    }

    if (fnt->rotate)
    {
      warning("Ignoring `-x' switch for non-subfont.");
      fnt->rotate = False;
    }

    if (fnt->write_enc)
    {
      warning("Ignoring `-w' switch for non-subfont.");
      fnt->write_enc = False;
    }

    if (fnt->y_offsetparam)
      warning("Ignoring `-y' switch for non-subfont.");
  }

  if (fnt->PSnames == Only)
  {
    if (fnt->pidparam || fnt->eidparam)
    {
      warning("Ignoring `-P' and `-E' options if `-N' switch is selected.");
      fnt->pidparam = NULL;
      fnt->eidparam = NULL;
    }
  }

  if (vpl_name)
    free(vpl_name);
  free(temp);
}
Beispiel #11
0
static void
handle_ping(const char * const data, const size_t size)
{
  handle_extension(data, size);
}
Beispiel #12
0
static void
handle_query(const struct gnutella_header *header,
  const char * const data, const size_t size)
{
  const char *end;

  if (size < 2) {
    printf("Too short:  %s\n", escape_buffer(data, size));
  } else {
    uint16_t flags;
    int swapped = 0;

    flags = peek_be16(data);
    if (!(flags & QUERY_F_MARK)) {
        uint16_t mask = QUERY_F_MARK | QUERY_F_GGEP_H | QUERY_F_LEAF_GUIDED;
        uint16_t reversed;

        /* Try to decode endian swapped flags as emitted by RAZA */
        reversed = peek_le16(data);
        if ((reversed & mask) == mask) {
          swapped = 1;
          flags = reversed;
        }
    }
    if (flags & QUERY_F_MARK) {
      int is_firewalled = flags & QUERY_F_FIREWALLED;
      int want_xml = flags & QUERY_F_WANT_XML;
      int leaf_guided = flags & QUERY_F_LEAF_GUIDED;
      int ggep_h = flags & QUERY_F_GGEP_H;
      int is_oob = flags & QUERY_F_OOB;
      int rudp_supp = flags & QUERY_F_RUDP;
      int bit8 = flags & QUERY_F_BIT8;
      
      printf("Flags:  %s%s%s%s%s%s%s%s\n"
        , is_firewalled ? "firewalled " : ""
        , want_xml ? "XML " : ""
        , leaf_guided ? "leaf-guided " : ""
        , ggep_h ? "GGEP/H " : ""
        , is_oob ? "OOB " : ""
        , rudp_supp ? "RUDP " : ""
        , bit8 ? "bit8 " : ""
        , swapped ? "[SWAPPED]" : ""
      );
      if (is_oob) {
        printf("OOB address:  %s\n",
          net_addr_port_to_string(net_addr_peek_ipv4(&header->guid.data[0]),
            peek_le16(&header->guid.data[13]))
        );
      }
    } else {
      printf("Flags:  0x%04X\n", flags);
    }

    end = memchr(&data[2], '\0', size - 2);
    if (end) {
      end++;
    } else {
      end = &data[size];
    }
    printf("Query:  \"%s\"\n", escape_buffer(&data[2], (end - &data[2]) - 1));

    if (&data[size] != end) {
      size_t ext_len;
      
      ext_len = &data[size] - end;
      if ('\0' == data[size - 1]) {
        ext_len--;
      }
      handle_extension(end, ext_len);
    }
  }
}
Beispiel #13
0
static void
handle_qhit(const char *data, size_t size)
{
  const struct gnutella_qhit_header *header;
  const struct gnutella_guid *guid;
  const struct gnutella_qhit_item *item;
  size_t guid_offset = size - sizeof *guid;
  unsigned hits;
  size_t pos;
  
  RUNTIME_ASSERT(size <= GNUTELLA_MAX_PAYLOAD);
  
  if (size < sizeof *header) {
    fprintf(stderr, "handle_qhit(): Too little payload for header.\n");
    return;
  }
  header = cast_to_const_void_ptr(data);
  
  hits = (unsigned char) header->hits;
  printf("Hits: %u\n", hits);
  printf("Address: %s\n",
    net_addr_port_to_string(net_addr_peek_ipv4(cast_to_const_char_ptr(header->addr)),
      peek_le16(header->port)));
  printf("Speed: %lu\n", (unsigned long) peek_le32(header->speed));

  if (size < sizeof *header + sizeof *guid) {
    fprintf(stderr, "handle_qhit(): Insufficient payload for query hit.\n");
    return;
  }
  if (size >= sizeof *header + sizeof *guid) {
    
    guid = cast_to_const_void_ptr(&data[guid_offset]);
    printf("Servent ID: %08lx-%08lx-%08lx-%08lx\n",
        (unsigned long) peek_be32(&guid->data[0]),
        (unsigned long) peek_be32(&guid->data[4]),
        (unsigned long) peek_be32(&guid->data[8]),
        (unsigned long) peek_be32(&guid->data[12]));
  }
  printf("----\n");

  pos = sizeof *header;
  for (/* NOTHING */; hits > 0; hits--) {
    const char *nul_ptr;
   
    if (pos >= guid_offset || guid_offset - pos < sizeof *item + 2)
      break;

    item = cast_to_const_void_ptr(&data[pos]);
    printf("Index: %lu\n", (unsigned long) peek_le32(item->index));
    printf("Size:  %lu\n", (unsigned long) peek_le32(item->size));

    pos += sizeof *item; 

    nul_ptr = memchr(&data[pos], 0, guid_offset - pos);
    if (!nul_ptr) {
      fprintf(stderr, "handle_qhit(): Non-terminated filename.\n");
      return;
    } else {
      size_t len;

      len = (nul_ptr - &data[pos]);
      if (len > (((size_t) -1) / 4 - 1)) {
        fprintf(stderr, "handle_qhit(): Filename is too long.\n");
        /* Ignore */
      } else {
        const char *p;
        size_t avail;
        
        printf("Filename: ");

        avail = len;
        p = &data[pos];
        while (avail > 0) {
          uint32_t cp;
          cp = utf8_decode(p, avail);
          if ((uint32_t) -1 != cp) {
            uint8_t u_len, i;

            u_len = utf8_first_byte_length_hint((unsigned char) *p);
            RUNTIME_ASSERT(u_len > 0);
            RUNTIME_ASSERT(avail >= u_len);
            avail -= u_len;

            if (cp >= 0x20 && cp != 0x7f) {
              for (i = 0; i < u_len; i++) {
                putchar((unsigned char) p[i]);
              }
            } else {
              char ch = cp & 0xff;
              printf("%s", escape_buffer(&ch, 1)); 
            }
            
            p += u_len;
          } else {
            if (verbosity > 0) {
              fprintf(stderr, "handle_qhit(): Invalid UTF-8.\n");
            }
            break;
          }
        }
      }
      printf("\n");

      pos += len;
    }

    RUNTIME_ASSERT(nul_ptr);
    RUNTIME_ASSERT(&data[pos] == nul_ptr);
    RUNTIME_ASSERT('\0' == *nul_ptr);

    pos++;
    RUNTIME_ASSERT(pos <= guid_offset);

    nul_ptr = memchr(&data[pos], 0, guid_offset - pos);
    if (!nul_ptr) {
      fprintf(stderr, "handle_qhit(): Non-terminated extension block.\n");
      return;
    } else if (nul_ptr != &data[pos]) {
      size_t len = nul_ptr - &data[pos];
      
      printf("Extension size:  %lu\n", (unsigned long) len);
     
      handle_extension(&data[pos], len);
      pos += len;
    }

    RUNTIME_ASSERT(nul_ptr);
    RUNTIME_ASSERT(&data[pos] == nul_ptr);
    RUNTIME_ASSERT('\0' == *nul_ptr);

    pos++;
    RUNTIME_ASSERT(pos <= guid_offset);

    printf("------\n");
  }

  if (hits > 0) {
    fprintf(stderr, "handle_qhit(): Expected %u more hits.\n", hits);
  }

  if (pos < guid_offset) {
      static const unsigned vendor_id_len = 4;
      
      printf("Extended QHD size:  %lu\n", (unsigned long) guid_offset - pos);
      if (guid_offset - pos >= vendor_id_len) {

        printf("Vendor ID: %s\n", escape_buffer(&data[pos], vendor_id_len));

        pos += vendor_id_len;
        if (pos < guid_offset) {
          uint8_t open_data_size = data[pos];
          bool has_ggep = false;
          
          printf("Open data size:  %u\n", open_data_size);
          pos++;

          if (open_data_size > guid_offset - pos) {
            printf("Open data size is too large.\n");
            return;
          }

          if (open_data_size >= 2) {
            uint8_t mask = data[pos];
            uint8_t value = data[pos + 1];
          
            printf("mask:  0x%02x\n", mask);
            printf("value: 0x%02x\n", value);
            
            if (0x20 & mask) {
              has_ggep = 0x20 & value;
              printf("Has GGEP: %s\n", has_ggep ? "yes" : "no");
            }
            if (0x10 & mask) {
              printf("Has speed: %s\n", (0x10 & value) ? "yes" : "no");
            }
            if (0x08 & mask) {
              printf("Has uploaded: %s\n", (0x08 & value) ? "yes" : "no");
            }
            if (0x04 & mask) {
              printf("Busy: %s\n", (0x04 & value) ? "yes" : "no");
            }
            /* mask and value are swapped */
            if (0x01 & value) {
              printf("Must push: %s\n", (0x01 & mask) ? "yes" : "no");
            }
          }

          pos += open_data_size;

          if (pos < guid_offset) {
            size_t priv_data_size = guid_offset - pos;
            static const char id_deflate[] = "{deflate}";
            const char *priv_data, *x;
            
            priv_data = &data[pos];
            priv_data_size = guid_offset - pos;
            
            printf("Private data area size:  %lu\n",
              (unsigned long) priv_data_size);

            handle_extension(priv_data, priv_data_size);

            x = compat_memmem(priv_data, priv_data_size,
                    id_deflate, STATIC_STRLEN(id_deflate));
            if (x) {
              char buf[64 * 1024];
              const char *src;
              size_t n, src_len;

              src = &x[STATIC_STRLEN(id_deflate)];
              src_len = priv_data_size - STATIC_STRLEN(id_deflate);
              n = buffer_inflate(buf, sizeof buf, src, src_len);
              if ((size_t) -1 != n) {
                printf("Inflated:  %s\n", escape_buffer(buf, n));
              }
            }

            pos += priv_data_size;
          }

          RUNTIME_ASSERT(pos == guid_offset);
        }
      }
  }
  
  printf("----\n");
}