static Image *ReadOneJNGImage(MngInfo *mng_info,
    const ImageInfo *image_info, ExceptionInfo *exception)
{
  Image
    *alpha_image,
    *color_image,
    *image,
    *jng_image;

  ImageInfo
    *alpha_image_info,
    *color_image_info;

  MagickBooleanType
    logging;

  int
    unique_filenames;

  ssize_t
    y;

  MagickBooleanType
    status;

  png_uint_32
    jng_height,
    jng_width;

  png_byte
    jng_color_type,
    jng_image_sample_depth,
    jng_image_compression_method,
    jng_image_interlace_method,
    jng_alpha_sample_depth,
    jng_alpha_compression_method,
    jng_alpha_filter_method,
    jng_alpha_interlace_method;

  register const PixelPacket
    *s;

  register ssize_t
    i,
    x;

  register PixelPacket
    *q;

  register unsigned char
    *p;

  unsigned int
    read_JSEP,
    reading_idat;

  size_t
    length;

  jng_alpha_compression_method=0;
  jng_alpha_sample_depth=8;
  jng_color_type=0;
  jng_height=0;
  jng_width=0;
  alpha_image=(Image *) NULL;
  color_image=(Image *) NULL;
  alpha_image_info=(ImageInfo *) NULL;
  color_image_info=(ImageInfo *) NULL;
  unique_filenames=0;

  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
    "  Enter ReadOneJNGImage()");

  image=mng_info->image;

  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
    {
      /*
        Allocate next image structure.
      */
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "  AcquireNextImage()");

      AcquireNextImage(image_info,image);

      if (GetNextImageInList(image) == (Image *) NULL)
        return(DestroyImageList(image));

      image=SyncNextImageInList(image);
    }
  mng_info->image=image;

  /*
    Signature bytes have already been read.
  */

  read_JSEP=MagickFalse;
  reading_idat=MagickFalse;
  for (;;)
  {
    char
      type[MaxTextExtent];

    unsigned char
      *chunk;

    unsigned int
      count;

    /*
      Read a new JNG chunk.
    */
    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
      2*GetBlobSize(image));

    if (status == MagickFalse)
      break;

    type[0]='\0';
    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
    length=(size_t) ReadBlobMSBLong(image);
    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);

    if (logging != MagickFalse)
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
        type[0],type[1],type[2],type[3],(double) length);

    if (length > PNG_UINT_31_MAX || count == 0)
      {
        DestroyJNG(NULL,&color_image,&color_image_info,
          &alpha_image,&alpha_image_info);
        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
      }

    if (length > GetBlobSize(image))
      {
        DestroyJNG(NULL,&color_image,&color_image_info,
          &alpha_image,&alpha_image_info);
        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
      }
    p=NULL;
    chunk=(unsigned char *) NULL;

    if (length != 0)
      {
        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));

        if (chunk == (unsigned char *) NULL)
          {
            DestroyJNG(NULL,&color_image,&color_image_info,
              &alpha_image,&alpha_image_info);
            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
          }

        for (i=0; i < (ssize_t) length; i++)
        {
          int
            c;

          c=ReadBlobByte(image);
          if (c == EOF)
            break;
          chunk[i]=(unsigned char) c;
        }
        for ( ; i < (ssize_t) length; i++)
          chunk[i]='\0';

        p=chunk;
      }

    (void) ReadBlobMSBLong(image);  /* read crc word */

    if (memcmp(type,mng_JHDR,4) == 0)
      {
        if (length == 16)
          {
            jng_width=(png_uint_32)mng_get_long(p);
            jng_height=(png_uint_32)mng_get_long(&p[4]);
            if ((jng_width == 0) || (jng_height == 0))
              {
                DestroyJNG(chunk,&color_image,&color_image_info,
                  &alpha_image,&alpha_image_info);
                ThrowReaderException(CorruptImageError,
                  "NegativeOrZeroImageSize");
              }
            jng_color_type=p[8];
            jng_image_sample_depth=p[9];
            jng_image_compression_method=p[10];
            jng_image_interlace_method=p[11];

            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
              NoInterlace;

            jng_alpha_sample_depth=p[12];
            jng_alpha_compression_method=p[13];
            jng_alpha_filter_method=p[14];
            jng_alpha_interlace_method=p[15];

            if (logging != MagickFalse)
              {
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_width:      %16lu,    jng_height:     %16lu\n"
                  "    jng_color_type: %16d,     jng_image_sample_depth: %3d\n"
                  "    jng_image_compression_method:%3d",
                  (unsigned long) jng_width, (unsigned long) jng_height,
                  jng_color_type, jng_image_sample_depth,
                  jng_image_compression_method);

                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_image_interlace_method:  %3d"
                  "    jng_alpha_sample_depth:      %3d",
                  jng_image_interlace_method,
                  jng_alpha_sample_depth);

                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_alpha_compression_method:%3d\n"
                  "    jng_alpha_filter_method:     %3d\n"
                  "    jng_alpha_interlace_method:  %3d",
                  jng_alpha_compression_method,
                  jng_alpha_filter_method,
                  jng_alpha_interlace_method);
              }
          }

        chunk=(unsigned char *) RelinquishMagickMemory(chunk);

        if (jng_width > 65535 || jng_height > 65535 ||
             (long) jng_width > GetMagickResourceLimit(WidthResource) ||
             (long) jng_height > GetMagickResourceLimit(HeightResource))
          {
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
               "    JNG width or height too large: (%lu x %lu)",
                (long) jng_width, (long) jng_height);
            DestroyJNG(chunk,&color_image,&color_image_info,
              &alpha_image,&alpha_image_info);
            ThrowReaderException(CorruptImageError,"ImproperImageHeader");
          }

        continue;
      }

    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
      {
        /*
           o create color_image
           o open color_blob, attached to color_image
           o if (color type has alpha)
               open alpha_blob, attached to alpha_image
        */

        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Creating color_blob.");

        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));

        if (color_image_info == (ImageInfo *) NULL)
          {
            DestroyJNG(chunk,&color_image,&color_image_info,
              &alpha_image,&alpha_image_info);
            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
          }

        GetImageInfo(color_image_info);
        color_image=AcquireImage(color_image_info);
        if (color_image == (Image *) NULL)
        {
          DestroyJNG(chunk,&color_image,&color_image_info,
              &alpha_image,&alpha_image_info);
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        }

        (void) AcquireUniqueFilename(color_image->filename);
        unique_filenames++;
        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
          exception);

        if (status == MagickFalse)
          {
            DestroyJNG(chunk,&color_image,&color_image_info,
              &alpha_image,&alpha_image_info);
            return(DestroyImageList(image));
          }

        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
          {
            alpha_image_info=(ImageInfo *)
              AcquireMagickMemory(sizeof(ImageInfo));

            if (alpha_image_info == (ImageInfo *) NULL)
              {
                DestroyJNG(chunk,&color_image,&color_image_info,
                  &alpha_image,&alpha_image_info);
                ThrowReaderException(ResourceLimitError,
                  "MemoryAllocationFailed");
              }

            GetImageInfo(alpha_image_info);
            alpha_image=AcquireImage(alpha_image_info);

            if (alpha_image == (Image *) NULL)
              {
                  DestroyJNG(chunk,&color_image,&color_image_info,
                    &alpha_image,&alpha_image_info);
                ThrowReaderException(ResourceLimitError,
                  "MemoryAllocationFailed");
              }

            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Creating alpha_blob.");

            (void) AcquireUniqueFilename(alpha_image->filename);
            unique_filenames++;
            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
              exception);

            if (status == MagickFalse)
              {
                alpha_image=DestroyImage(alpha_image);
                alpha_image_info=DestroyImageInfo(alpha_image_info);
                color_image=DestroyImage(color_image);
                return(DestroyImageList(image));
              }

            if (jng_alpha_compression_method == 0)
              {
                unsigned char
                  data[18];

                if (logging != MagickFalse)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "    Writing IHDR chunk to alpha_blob.");

                (void) WriteBlob(alpha_image,8,(const unsigned char *)
                  "\211PNG\r\n\032\n");

                (void) WriteBlobMSBULong(alpha_image,13L);
                PNGType(data,mng_IHDR);
                LogPNGChunk(logging,mng_IHDR,13L);
                PNGLong(data+4,jng_width);
                PNGLong(data+8,jng_height);
                data[12]=jng_alpha_sample_depth;
                data[13]=0; /* color_type gray */
                data[14]=0; /* compression method 0 */
                data[15]=0; /* filter_method 0 */
                data[16]=0; /* interlace_method 0 */
                (void) WriteBlob(alpha_image,17,data);
                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
              }
          }
        reading_idat=MagickTrue;
      }

    if (memcmp(type,mng_JDAT,4) == 0)
      {
        /* Copy chunk to color_image->blob */

        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Copying JDAT chunk data to color_blob.");

        if ((length != 0) && (color_image != (Image *) NULL))
          (void) WriteBlob(color_image,length,chunk);
        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_IDAT,4) == 0)
      {
        png_byte
           data[5];

        /* Copy IDAT header and chunk data to alpha_image->blob */

        if (alpha_image != NULL && image_info->ping == MagickFalse)
          {
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Copying IDAT chunk data to alpha_blob.");

            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
            PNGType(data,mng_IDAT);
            LogPNGChunk(logging,mng_IDAT,length);
            (void) WriteBlob(alpha_image,4,data);
            (void) WriteBlob(alpha_image,length,chunk);
            (void) WriteBlobMSBULong(alpha_image,
              crc32(crc32(0,data,4),chunk,(uInt) length));
          }

        chunk=(unsigned char *) RelinquishMagickMemory(chunk);

        continue;
      }

    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
      {
        /* Copy chunk data to alpha_image->blob */

        if ((alpha_image != NULL) && (image_info->ping == MagickFalse) &&
            (length != 0))
          {
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Copying JDAA chunk data to alpha_blob.");

            (void) WriteBlob(alpha_image,length,chunk);
          }

        chunk=(unsigned char *) RelinquishMagickMemory(chunk);

        continue;
      }

    if (memcmp(type,mng_JSEP,4) == 0)
      {
        read_JSEP=MagickTrue;

        chunk=(unsigned char *) RelinquishMagickMemory(chunk);

        continue;
      }

    if (memcmp(type,mng_bKGD,4) == 0)
      {
        if (length == 2)
          {
            image->background_color.red=ScaleCharToQuantum(p[1]);
            image->background_color.green=image->background_color.red;
            image->background_color.blue=image->background_color.red;
          }

        if (length == 6)
          {
            image->background_color.red=ScaleCharToQuantum(p[1]);
            image->background_color.green=ScaleCharToQuantum(p[3]);
            image->background_color.blue=ScaleCharToQuantum(p[5]);
          }

        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_gAMA,4) == 0)
      {
        if (length == 4)
          image->gamma=((float) mng_get_long(p))*0.00001;

        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_cHRM,4) == 0)
      {
        if (length == 32)
          {
            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
          }

        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_sRGB,4) == 0)
      {
        if (length == 1)
          {
            image->rendering_intent=
              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
            image->gamma=1.000f/2.200f;
            image->chromaticity.red_primary.x=0.6400f;
            image->chromaticity.red_primary.y=0.3300f;
            image->chromaticity.green_primary.x=0.3000f;
            image->chromaticity.green_primary.y=0.6000f;
            image->chromaticity.blue_primary.x=0.1500f;
            image->chromaticity.blue_primary.y=0.0600f;
            image->chromaticity.white_point.x=0.3127f;
            image->chromaticity.white_point.y=0.3290f;
          }

        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_oFFs,4) == 0)
      {
        if (length > 8)
          {
            image->page.x=(ssize_t) mng_get_long(p);
            image->page.y=(ssize_t) mng_get_long(&p[4]);

            if ((int) p[8] != 0)
              {
                image->page.x/=10000;
                image->page.y/=10000;
              }
          }

        chunk=(unsigned char *) RelinquishMagickMemory(chunk);

        continue;
      }

    if (memcmp(type,mng_pHYs,4) == 0)
      {
        if (length > 8)
          {
            image->x_resolution=(double) mng_get_long(p);
            image->y_resolution=(double) mng_get_long(&p[4]);
            if ((int) p[8] == PNG_RESOLUTION_METER)
              {
                image->units=PixelsPerCentimeterResolution;
                image->x_resolution=image->x_resolution/100.0f;
                image->y_resolution=image->y_resolution/100.0f;
              }
          }

        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

#if 0
    if (memcmp(type,mng_iCCP,4) == 0)
      {
        /* To do: */
        chunk=(unsigned char *) RelinquishMagickMemory(chunk);

        continue;
      }
#endif

    chunk=(unsigned char *) RelinquishMagickMemory(chunk);

    if (memcmp(type,mng_IEND,4))
      continue;

    break;
  }

  /* IEND found */

  /*
    Finish up reading image data:

       o read main image from color_blob.

       o close color_blob.

       o if (color_type has alpha)
            if alpha_encoding is PNG
               read secondary image from alpha_blob via ReadPNG
            if alpha_encoding is JPEG
               read secondary image from alpha_blob via ReadJPEG

       o close alpha_blob.

       o copy intensity of secondary image into
         opacity samples of main image.

       o destroy the secondary image.
  */

  if (color_image_info == (ImageInfo *) NULL)
    {
      assert(color_image == (Image *) NULL);
      assert(alpha_image == (Image *) NULL);
      if (color_image != (Image *) NULL)
        color_image=DestroyImage(color_image);
      return(DestroyImageList(image));
    }

  if (color_image == (Image *) NULL)
    {
      assert(alpha_image == (Image *) NULL);
      ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
    }

  (void) SeekBlob(color_image,0,SEEK_SET);

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "    Reading jng_image from color_blob.");

  assert(color_image_info != (ImageInfo *) NULL);
  (void) FormatLocaleString(color_image_info->filename,MaxTextExtent,"jpeg:%s",
    color_image->filename);

  color_image_info->ping=MagickFalse;   /* To do: avoid this */
  jng_image=ReadImage(color_image_info,exception);

  (void) RelinquishUniqueFileResource(color_image->filename);
  unique_filenames--;
  color_image=DestroyImage(color_image);
  color_image_info=DestroyImageInfo(color_image_info);

  if (jng_image == (Image *) NULL)
  {
    DestroyJNG(NULL,NULL,NULL,&alpha_image,&alpha_image_info);
    return(DestroyImageList(image));
  }

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "    Copying jng_image pixels to main image.");
  image->columns=jng_width;
  image->rows=jng_height;
  length=image->columns*sizeof(PixelPacket);

  status=SetImageExtent(image,image->columns,image->rows);
  if (status == MagickFalse)
    {
      jng_image=DestroyImageList(jng_image);
      DestroyJNG(NULL,&color_image,&color_image_info,&alpha_image,
        &alpha_image_info);
      return(DestroyImageList(image));
    }
  if ((image->columns != jng_image->columns) ||
      (image->rows != jng_image->rows))
    {
      jng_image=DestroyImageList(jng_image);
      DestroyJNG(NULL,&color_image,&color_image_info,&alpha_image,
        &alpha_image_info);
      return(DestroyImageList(image));
    }

  for (y=0; y < (ssize_t) image->rows; y++)
  {
    s=GetVirtualPixels(jng_image,0,y,image->columns,1,exception);
    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    if ((s == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
      break;
    (void) memcpy(q,s,length);

    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
  }

  jng_image=DestroyImage(jng_image);

  if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
    {
      if (jng_alpha_compression_method == 0)
        {
          png_byte
            data[5];
          (void) WriteBlobMSBULong(alpha_image,0x00000000L);
          PNGType(data,mng_IEND);
          LogPNGChunk(logging,mng_IEND,0L);
          (void) WriteBlob(alpha_image,4,data);
          (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
        }

      (void) SeekBlob(alpha_image,0,SEEK_SET);

      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Reading opacity from alpha_blob.");

      (void) FormatLocaleString(alpha_image_info->filename,MaxTextExtent,
        "%s",alpha_image->filename);

      jng_image=ReadImage(alpha_image_info,exception);

      if (jng_image != (Image *) NULL)
        for (y=0; y < (ssize_t) image->rows; y++)
        {
          s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
          q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
          if ((s == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
            break;

          if (image->matte != MagickFalse)
            for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
              SetPixelOpacity(q,QuantumRange-GetPixelRed(s));

          else
            for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
            {
              SetPixelAlpha(q,GetPixelRed(s));
              if (GetPixelOpacity(q) != OpaqueOpacity)
                image->matte=MagickTrue;
            }

          if (SyncAuthenticPixels(image,exception) == MagickFalse)
            break;
        }
      (void) RelinquishUniqueFileResource(alpha_image->filename);
      unique_filenames--;
      alpha_image=DestroyImage(alpha_image);
      alpha_image_info=DestroyImageInfo(alpha_image_info);
      if (jng_image != (Image *) NULL)
        jng_image=DestroyImage(jng_image);
    }

  /* Read the JNG image.  */

  if (mng_info->mng_type == 0)
    {
      mng_info->mng_width=jng_width;
      mng_info->mng_height=jng_height;
    }

  if (image->page.width == 0 && image->page.height == 0)
    {
      image->page.width=jng_width;
      image->page.height=jng_height;
    }

  if (image->page.x == 0 && image->page.y == 0)
    {
      image->page.x=mng_info->x_off[mng_info->object_id];
      image->page.y=mng_info->y_off[mng_info->object_id];
    }

  else
    {
      image->page.y=mng_info->y_off[mng_info->object_id];
    }

  mng_info->image_found++;
  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
    2*GetBlobSize(image));

  if (status == MagickFalse)
    return(DestroyImageList(image));

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  exit ReadOneJNGImage(); unique_filenames=%d",unique_filenames);

  return(image);
}


static Image *ReadPICTImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
#define ThrowPICTException(exception,message) \
{ \
  if (tile_image != (Image *) NULL) \
    tile_image=DestroyImage(tile_image); \
  if (read_info != (ImageInfo *) NULL) \
    read_info=DestroyImageInfo(read_info); \
  ThrowReaderException((exception),(message)); \
}

  char
    geometry[MaxTextExtent],
    header_ole[4];

  Image
    *image,
    *tile_image;

  ImageInfo
    *read_info;

  IndexPacket
    index;

  int
    c,
    code;

  MagickBooleanType
    jpeg,
    status;

  PICTRectangle
    frame;

  PICTPixmap
    pixmap;

  register IndexPacket
    *indexes;

  register ssize_t
    x;

  register PixelPacket
    *q;

  register ssize_t
    i;

  size_t
    extent,
    length;

  ssize_t
    count,
    flags,
    j,
    version,
    y;

  StringInfo
    *profile;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  image=AcquireImage(image_info);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
    Read PICT header.
  */
  read_info=(ImageInfo *) NULL;
  tile_image=(Image *) NULL;
  pixmap.bits_per_pixel=0;
  pixmap.component_count=0;
  /*
    Skip header : 512 for standard PICT and 4, ie "PICT" for OLE2
  */
  header_ole[0]=ReadBlobByte(image);
  header_ole[1]=ReadBlobByte(image);
  header_ole[2]=ReadBlobByte(image);
  header_ole[3]=ReadBlobByte(image);
  if (!((header_ole[0] == 0x50) && (header_ole[1] == 0x49) &&
      (header_ole[2] == 0x43) && (header_ole[3] == 0x54)))
    for (i=0; i < 508; i++)
      if (ReadBlobByte(image) == EOF)
        break;
  (void) ReadBlobMSBShort(image);  /* skip picture size */
  if (ReadRectangle(image,&frame) == MagickFalse)
    ThrowPICTException(CorruptImageError,"ImproperImageHeader");
  while ((c=ReadBlobByte(image)) == 0) ;
  if (c != 0x11)
    ThrowPICTException(CorruptImageError,"ImproperImageHeader");
  version=(ssize_t) ReadBlobByte(image);
  if (version == 2)
    {
      c=ReadBlobByte(image);
      if (c != 0xff)
        ThrowPICTException(CorruptImageError,"ImproperImageHeader");
    }
  else
    if (version != 1)
      ThrowPICTException(CorruptImageError,"ImproperImageHeader");
  if ((frame.left < 0) || (frame.right < 0) || (frame.top < 0) ||
      (frame.bottom < 0) || (frame.left >= frame.right) ||
      (frame.top >= frame.bottom))
    ThrowPICTException(CorruptImageError,"ImproperImageHeader");
  /*
    Create black canvas.
  */
  flags=0;
  image->depth=8;
  image->columns=(unsigned int) (frame.right-frame.left);
  image->rows=(unsigned int) (frame.bottom-frame.top);
  image->x_resolution=DefaultResolution;
  image->y_resolution=DefaultResolution;
  image->units=UndefinedResolution;
  if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
    if (image->scene >= (image_info->scene+image_info->number_scenes-1))
      {
        (void) CloseBlob(image);
        return(GetFirstImageInList(image));
      }
  status=SetImageExtent(image,image->columns,image->rows);
  if (status != MagickFalse)
    status=ResetImagePixels(image,exception);
  if (status == MagickFalse)
    {
      InheritException(exception,&image->exception);
      return(DestroyImageList(image));
    }
  /*
    Interpret PICT opcodes.
  */
  jpeg=MagickFalse;
  for (code=0; EOFBlob(image) == MagickFalse; )
  {
    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    if ((version == 1) || ((TellBlob(image) % 2) != 0))
      code=ReadBlobByte(image);
    if (version == 2)
      code=ReadBlobMSBSignedShort(image);
    if (code < 0)
      break;
    if (code == 0)
      continue;
    if (code > 0xa1)
      {
        if (image->debug != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%04X:",code);
      }
    else
      {
        if (image->debug != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  %04X %s: %s",code,codes[code].name,codes[code].description);
        switch (code)
        {
          case 0x01:
          {
            /*
              Clipping rectangle.
            */
            length=ReadBlobMSBShort(image);
            if (length != 0x000a)
              {
                for (i=0; i < (ssize_t) (length-2); i++)
                  if (ReadBlobByte(image) == EOF)
                    break;
                break;
              }
            if (ReadRectangle(image,&frame) == MagickFalse)
              ThrowPICTException(CorruptImageError,"ImproperImageHeader");
            if (((frame.left & 0x8000) != 0) || ((frame.top & 0x8000) != 0))
              break;
            image->columns=(size_t) (frame.right-frame.left);
            image->rows=(size_t) (frame.bottom-frame.top);
            status=SetImageExtent(image,image->columns,image->rows);
            if (status != MagickFalse)
              status=ResetImagePixels(image,&image->exception);
            if (status == MagickFalse)
              {
                InheritException(exception,&image->exception);
                return(DestroyImageList(image));
              }
            break;
          }
          case 0x12:
          case 0x13:
          case 0x14:
          {
            ssize_t
              pattern;

            size_t
              height,
              width;

            /*
              Skip pattern definition.
            */
            pattern=(ssize_t) ReadBlobMSBShort(image);
            for (i=0; i < 8; i++)
              if (ReadBlobByte(image) == EOF)
                break;
            if (pattern == 2)
              {
                for (i=0; i < 5; i++)
                  if (ReadBlobByte(image) == EOF)
                    break;
                break;
              }
            if (pattern != 1)
              ThrowPICTException(CorruptImageError,"UnknownPatternType");
            length=ReadBlobMSBShort(image);
            if (ReadRectangle(image,&frame) == MagickFalse)
              ThrowPICTException(CorruptImageError,"ImproperImageHeader");
            if (ReadPixmap(image,&pixmap) == MagickFalse)
              ThrowPICTException(CorruptImageError,"ImproperImageHeader");
            image->depth=(size_t) pixmap.component_size;
            image->x_resolution=1.0*pixmap.horizontal_resolution;
            image->y_resolution=1.0*pixmap.vertical_resolution;
            image->units=PixelsPerInchResolution;
            (void) ReadBlobMSBLong(image);
            flags=(ssize_t) ReadBlobMSBShort(image);
            length=ReadBlobMSBShort(image);
            for (i=0; i <= (ssize_t) length; i++)
              (void) ReadBlobMSBLong(image);
            width=(size_t) (frame.bottom-frame.top);
            height=(size_t) (frame.right-frame.left);
            if (pixmap.bits_per_pixel <= 8)
              length&=0x7fff;
            if (pixmap.bits_per_pixel == 16)
              width<<=1;
            if (length == 0)
              length=width;
            if (length < 8)
              {
                for (i=0; i < (ssize_t) (length*height); i++)
                  if (ReadBlobByte(image) == EOF)
                    break;
              }
            else
              for (i=0; i < (ssize_t) height; i++)
              {
                if (EOFBlob(image) != MagickFalse)
                  break;
                if (length > 200)
                  {
                    for (j=0; j < (ssize_t) ReadBlobMSBShort(image); j++)
                      if (ReadBlobByte(image) == EOF)
                        break;
                  }
                else
                  for (j=0; j < (ssize_t) ReadBlobByte(image); j++)
                    if (ReadBlobByte(image) == EOF)
                      break;
              }
            break;
          }
          case 0x1b:
          {
            /*
              Initialize image background color.
            */
            image->background_color.red=(Quantum)
              ScaleShortToQuantum(ReadBlobMSBShort(image));
            image->background_color.green=(Quantum)
              ScaleShortToQuantum(ReadBlobMSBShort(image));
            image->background_color.blue=(Quantum)
              ScaleShortToQuantum(ReadBlobMSBShort(image));
            break;
          }
          case 0x70:
          case 0x71:
          case 0x72:
          case 0x73:
          case 0x74:
          case 0x75:
          case 0x76:
          case 0x77:
          {
            /*
              Skip polygon or region.
            */
            length=ReadBlobMSBShort(image);
            for (i=0; i < (ssize_t) (length-2); i++)
              if (ReadBlobByte(image) == EOF)
                break;
            break;
          }
          case 0x90:
          case 0x91:
          case 0x98:
          case 0x99:
          case 0x9a:
          case 0x9b:
          {
            ssize_t
              bytes_per_line;

            PICTRectangle
              source,
              destination;

            register unsigned char
              *p;

            size_t
              j;

            unsigned char
              *pixels;

            /*
              Pixmap clipped by a rectangle.
            */
            bytes_per_line=0;
            if ((code != 0x9a) && (code != 0x9b))
              bytes_per_line=(ssize_t) ReadBlobMSBShort(image);
            else
              {
                (void) ReadBlobMSBShort(image);
                (void) ReadBlobMSBShort(image);
                (void) ReadBlobMSBShort(image);
              }
            if (ReadRectangle(image,&frame) == MagickFalse)
              ThrowPICTException(CorruptImageError,"ImproperImageHeader");
            /*
              Initialize tile image.
            */
            tile_image=CloneImage(image,(size_t) (frame.right-frame.left),
              (size_t) (frame.bottom-frame.top),MagickTrue,exception);
            if (tile_image == (Image *) NULL)
              ThrowPICTException(CorruptImageError,"ImproperImageHeader");
            if ((code == 0x9a) || (code == 0x9b) ||
                ((bytes_per_line & 0x8000) != 0))
              {
                if (ReadPixmap(image,&pixmap) == MagickFalse)
                  ThrowPICTException(CorruptImageError,"ImproperImageHeader");
                tile_image->depth=(size_t) pixmap.component_size;
                tile_image->matte=pixmap.component_count == 4 ?
                  MagickTrue : MagickFalse;
                tile_image->x_resolution=(double) pixmap.horizontal_resolution;
                tile_image->y_resolution=(double) pixmap.vertical_resolution;
                tile_image->units=PixelsPerInchResolution;
                if (tile_image->matte != MagickFalse)
                  (void) SetImageAlphaChannel(tile_image,OpaqueAlphaChannel);
              }
            if ((code != 0x9a) && (code != 0x9b))
              {
                /*
                  Initialize colormap.
                */
                tile_image->colors=2;
                if ((bytes_per_line & 0x8000) != 0)
                  {
                    (void) ReadBlobMSBLong(image);
                    flags=(ssize_t) ReadBlobMSBShort(image);
                    tile_image->colors=1UL*ReadBlobMSBShort(image)+1;
                  }
                status=AcquireImageColormap(tile_image,tile_image->colors);
                if (status == MagickFalse)
                  ThrowPICTException(ResourceLimitError,
                    "MemoryAllocationFailed");
                if ((bytes_per_line & 0x8000) != 0)
                  {
                    for (i=0; i < (ssize_t) tile_image->colors; i++)
                    {
                      j=ReadBlobMSBShort(image) % tile_image->colors;
                      if ((flags & 0x8000) != 0)
                        j=(size_t) i;
                      tile_image->colormap[j].red=(Quantum)
                        ScaleShortToQuantum(ReadBlobMSBShort(image));
                      tile_image->colormap[j].green=(Quantum)
                        ScaleShortToQuantum(ReadBlobMSBShort(image));
                      tile_image->colormap[j].blue=(Quantum)
                        ScaleShortToQuantum(ReadBlobMSBShort(image));
                    }
                  }
                else
                  {
                    for (i=0; i < (ssize_t) tile_image->colors; i++)
                    {
                      tile_image->colormap[i].red=(Quantum) (QuantumRange-
                        tile_image->colormap[i].red);
                      tile_image->colormap[i].green=(Quantum) (QuantumRange-
                        tile_image->colormap[i].green);
                      tile_image->colormap[i].blue=(Quantum) (QuantumRange-
                        tile_image->colormap[i].blue);
                    }
                  }
              }
            if (EOFBlob(image) != MagickFalse)
              ThrowPICTException(CorruptImageError,
                "InsufficientImageDataInFile");
            if (ReadRectangle(image,&source) == MagickFalse)
              ThrowPICTException(CorruptImageError,"ImproperImageHeader");
            if (ReadRectangle(image,&destination) == MagickFalse)
              ThrowPICTException(CorruptImageError,"ImproperImageHeader");
            (void) ReadBlobMSBShort(image);
            if ((code == 0x91) || (code == 0x99) || (code == 0x9b))
              {
                /*
                  Skip region.
                */
                length=ReadBlobMSBShort(image);
                for (i=0; i < (ssize_t) (length-2); i++)
                  if (ReadBlobByte(image) == EOF)
                    break;
              }
            if ((code != 0x9a) && (code != 0x9b) &&
                (bytes_per_line & 0x8000) == 0)
              pixels=DecodeImage(image,tile_image,(size_t) bytes_per_line,1,
                &extent);
            else
              pixels=DecodeImage(image,tile_image,(unsigned int) bytes_per_line,
                (unsigned int) pixmap.bits_per_pixel,&extent);
            if (pixels == (unsigned char *) NULL)
              ThrowPICTException(CorruptImageError,"UnableToUncompressImage");
            /*
              Convert PICT tile image to pixel packets.
            */
            p=pixels;
            for (y=0; y < (ssize_t) tile_image->rows; y++)
            {
              if (p > (pixels+extent+image->columns))
                {
                  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
                  ThrowPICTException(CorruptImageError,"NotEnoughPixelData");
                }
              q=QueueAuthenticPixels(tile_image,0,y,tile_image->columns,1,
                exception);
              if (q == (PixelPacket *) NULL)
                break;
              indexes=GetAuthenticIndexQueue(tile_image);
              for (x=0; x < (ssize_t) tile_image->columns; x++)
              {
                if (tile_image->storage_class == PseudoClass)
                  {
                    index=ConstrainColormapIndex(tile_image,*p);
                    SetPixelIndex(indexes+x,index);
                    SetPixelRed(q,
                      tile_image->colormap[(ssize_t) index].red);
                    SetPixelGreen(q,
                      tile_image->colormap[(ssize_t) index].green);
                    SetPixelBlue(q,
                      tile_image->colormap[(ssize_t) index].blue);
                  }
                else
                  {
                    if (pixmap.bits_per_pixel == 16)
                      {
                        i=(ssize_t) (*p++);
                        j=(*p);
                        SetPixelRed(q,ScaleCharToQuantum(
                          (unsigned char) ((i & 0x7c) << 1)));
                        SetPixelGreen(q,ScaleCharToQuantum(
                          (unsigned char) (((i & 0x03) << 6) |
                          ((j & 0xe0) >> 2))));
                        SetPixelBlue(q,ScaleCharToQuantum(
                          (unsigned char) ((j & 0x1f) << 3)));
                      }
                    else
                      if (tile_image->matte == MagickFalse)
                        {
                          if (p > (pixels+extent+2*image->columns))
                            ThrowPICTException(CorruptImageError,
                              "NotEnoughPixelData");
                          SetPixelRed(q,ScaleCharToQuantum(*p));
                          SetPixelGreen(q,ScaleCharToQuantum(
                            *(p+tile_image->columns)));
                          SetPixelBlue(q,ScaleCharToQuantum(
                            *(p+2*tile_image->columns)));
                        }
                      else
                        {
                          if (p > (pixels+extent+3*image->columns))
                            ThrowPICTException(CorruptImageError,
                              "NotEnoughPixelData");
                          SetPixelAlpha(q,ScaleCharToQuantum(*p));
                          SetPixelRed(q,ScaleCharToQuantum(
                            *(p+tile_image->columns)));
                          SetPixelGreen(q,ScaleCharToQuantum(
                            *(p+2*tile_image->columns)));
                          SetPixelBlue(q,ScaleCharToQuantum(
                            *(p+3*tile_image->columns)));
                        }
                  }
                p++;
                q++;
              }
              if (SyncAuthenticPixels(tile_image,exception) == MagickFalse)
                break;
              if ((tile_image->storage_class == DirectClass) &&
                  (pixmap.bits_per_pixel != 16))
                {
                  p+=(pixmap.component_count-1)*tile_image->columns;
                  if (p < pixels)
                    break;
                }
              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                tile_image->rows);
              if (status == MagickFalse)
                break;
            }
            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
            if ((jpeg == MagickFalse) && (EOFBlob(image) == MagickFalse))
              if ((code == 0x9a) || (code == 0x9b) ||
                  ((bytes_per_line & 0x8000) != 0))
                (void) CompositeImage(image,CopyCompositeOp,tile_image,
                  (ssize_t) destination.left,(ssize_t) destination.top);
            tile_image=DestroyImage(tile_image);
            break;
          }
          case 0xa1:
          {
            unsigned char
              *info;

            size_t
              type;

            /*
              Comment.
            */
            type=ReadBlobMSBShort(image);
            length=ReadBlobMSBShort(image);
            if (length == 0)
              break;
            (void) ReadBlobMSBLong(image);
            length-=MagickMin(length,4);
            if (length == 0)
              break;
            info=(unsigned char *) AcquireQuantumMemory(length,sizeof(*info));
            if (info == (unsigned char *) NULL)
              break;
            count=ReadBlob(image,length,info);
            if (count != (ssize_t) length)
              {
                info=(unsigned char *) RelinquishMagickMemory(info);
                ThrowPICTException(ResourceLimitError,"UnableToReadImageData");
              }
            switch (type)
            {
              case 0xe0:
              {
                profile=BlobToStringInfo((const void *) NULL,length);
                SetStringInfoDatum(profile,info);
                status=SetImageProfile(image,"icc",profile);
                profile=DestroyStringInfo(profile);
                if (status == MagickFalse)
                  {
                    info=(unsigned char *) RelinquishMagickMemory(info);
                    ThrowPICTException(ResourceLimitError,
                      "MemoryAllocationFailed");
                  }
                break;
              }
              case 0x1f2:
              {
                profile=BlobToStringInfo((const void *) NULL,length);
                SetStringInfoDatum(profile,info);
                status=SetImageProfile(image,"iptc",profile);
                if (status == MagickFalse)
                  {
                    info=(unsigned char *) RelinquishMagickMemory(info);
                    ThrowPICTException(ResourceLimitError,
                      "MemoryAllocationFailed");
                  }
                profile=DestroyStringInfo(profile);
                break;
              }
              default:
                break;
            }
            info=(unsigned char *) RelinquishMagickMemory(info);
            break;
          }
          default:
          {
            /*
              Skip to next op code.
            */
            if (codes[code].length == -1)
              (void) ReadBlobMSBShort(image);
            else
              for (i=0; i < (ssize_t) codes[code].length; i++)
                if (ReadBlobByte(image) == EOF)
                  break;
          }
        }
      }
    if (code == 0xc00)
      {
        /*
          Skip header.
        */
        for (i=0; i < 24; i++)
          if (ReadBlobByte(image) == EOF)
            break;
        continue;
      }
    if (((code >= 0xb0) && (code <= 0xcf)) ||
        ((code >= 0x8000) && (code <= 0x80ff)))
      continue;
    if (code == 0x8200)
      {
        char
          filename[MaxTextExtent];

        FILE
          *file;

        int
          unique_file;

        /*
          Embedded JPEG.
        */
        jpeg=MagickTrue;
        read_info=CloneImageInfo(image_info);
        SetImageInfoBlob(read_info,(void *) NULL,0);
        file=(FILE *) NULL;
        unique_file=AcquireUniqueFileResource(filename);
        (void) FormatLocaleString(read_info->filename,MaxTextExtent,"jpeg:%s",
          filename);
        if (unique_file != -1)
          file=fdopen(unique_file,"wb");
        if ((unique_file == -1) || (file == (FILE *) NULL))
          {
            (void) RelinquishUniqueFileResource(read_info->filename);
            (void) CopyMagickString(image->filename,read_info->filename,
              MaxTextExtent);
            ThrowPICTException(FileOpenError,"UnableToCreateTemporaryFile");
          }
        length=ReadBlobMSBLong(image);
        if (length > 154)
          {
            for (i=0; i < 6; i++)
              (void) ReadBlobMSBLong(image);
            if (ReadRectangle(image,&frame) == MagickFalse)
              {
                (void) fclose(file);
                (void) RelinquishUniqueFileResource(read_info->filename);
                ThrowPICTException(CorruptImageError,"ImproperImageHeader");
              }
            for (i=0; i < 122; i++)
              if (ReadBlobByte(image) == EOF)
                break;
            for (i=0; i < (ssize_t) (length-154); i++)
            {
              c=ReadBlobByte(image);
              if (c == EOF)
                break;
              if (fputc(c,file) != c)
                break;
            }
          }
        (void) fclose(file);
        (void) close(unique_file);
        tile_image=ReadImage(read_info,exception);
        (void) RelinquishUniqueFileResource(filename);
        read_info=DestroyImageInfo(read_info);
        if (tile_image == (Image *) NULL)
          continue;
        (void) FormatLocaleString(geometry,MaxTextExtent,"%.20gx%.20g",
          (double) MagickMax(image->columns,tile_image->columns),
          (double) MagickMax(image->rows,tile_image->rows));
        (void) SetImageExtent(image,
          MagickMax(image->columns,tile_image->columns),
          MagickMax(image->rows,tile_image->rows));
        (void) TransformImageColorspace(image,tile_image->colorspace);
        (void) CompositeImage(image,CopyCompositeOp,tile_image,(ssize_t)
          frame.left,(ssize_t) frame.right);
        image->compression=tile_image->compression;
        tile_image=DestroyImage(tile_image);
        continue;
      }
    if ((code == 0xff) || (code == 0xffff))
      break;
    if (((code >= 0xd0) && (code <= 0xfe)) ||
        ((code >= 0x8100) && (code <= 0xffff)))
      {
        /*
          Skip reserved.
        */
        length=ReadBlobMSBShort(image);
        for (i=0; i < (ssize_t) length; i++)
          if (ReadBlobByte(image) == EOF)
            break;
        continue;
      }
    if ((code >= 0x100) && (code <= 0x7fff))
      {
        /*
          Skip reserved.
        */
        length=(size_t) ((code >> 7) & 0xff);
        for (i=0; i < (ssize_t) length; i++)
          if (ReadBlobByte(image) == EOF)
            break;
        continue;
      }
  }
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}


int nf_ct_frag6_init(void)
{
	int ret = 0;

	nf_frags.constructor = ip6frag_init;
	nf_frags.destructor = NULL;
	nf_frags.qsize = sizeof(struct frag_queue);
	nf_frags.frag_expire = nf_ct_frag6_expire;
	nf_frags.frags_cache_name = nf_frags_cache_name;
	nf_frags.rhash_params = nfct_rhash_params;
	ret = inet_frags_init(&nf_frags);
	if (ret)
		goto out;
	ret = register_pernet_subsys(&nf_ct_net_ops);
	if (ret)
		inet_frags_fini(&nf_frags);

out:
	return ret;
}


static void ipq_kill(struct ipq *ipq)
{
	inet_frag_kill(&ipq->q);
}


static void nf_ct_frag6_expire(struct timer_list *t)
{
	struct inet_frag_queue *frag = from_timer(frag, t, timer);
	struct frag_queue *fq;
	struct net *net;

	fq = container_of(frag, struct frag_queue, q);
	net = container_of(fq->q.net, struct net, nf_frag.frags);

	ip6frag_expire_frag_queue(net, fq);
}


static u8 ip4_frag_ecn(u8 tos)
{
	return 1 << (tos & INET_ECN_MASK);
}


struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user)
{
	struct iphdr iph;
	int netoff;
	u32 len;

	if (skb->protocol != htons(ETH_P_IP))
		return skb;

	netoff = skb_network_offset(skb);

	if (skb_copy_bits(skb, netoff, &iph, sizeof(iph)) < 0)
		return skb;

	if (iph.ihl < 5 || iph.version != 4)
		return skb;

	len = ntohs(iph.tot_len);
	if (skb->len < netoff + len || len < (iph.ihl * 4))
		return skb;

	if (ip_is_fragment(&iph)) {
		skb = skb_share_check(skb, GFP_ATOMIC);
		if (skb) {
			if (!pskb_may_pull(skb, netoff + iph.ihl * 4))
				return skb;
			if (pskb_trim_rcsum(skb, netoff + len))
				return skb;
			memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
			if (ip_defrag(net, skb, user))
				return NULL;
			skb_clear_hash(skb);
		}
	}
	return skb;
}


void die(const char *str, struct pt_regs *regs, long err)
{
	unsigned long flags = oops_begin();
	int sig = SIGSEGV;

	if (__die(str, regs, err))
		sig = 0;
	oops_end(flags, regs, sig);
}


force_sig_info_fault(int si_signo, int si_code, unsigned long address,
		     struct task_struct *tsk, u32 *pkey, int fault)
{
	unsigned lsb = 0;
	siginfo_t info;

	clear_siginfo(&info);
	info.si_signo	= si_signo;
	info.si_errno	= 0;
	info.si_code	= si_code;
	info.si_addr	= (void __user *)address;
	if (fault & VM_FAULT_HWPOISON_LARGE)
		lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));
	if (fault & VM_FAULT_HWPOISON)
		lsb = PAGE_SHIFT;
	info.si_addr_lsb = lsb;

	fill_sig_info_pkey(si_signo, si_code, &info, pkey);

	force_sig_info(si_signo, &info, tsk);
}


bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
		      unsigned long address, struct vm_area_struct *vma)
{
	/*
	 * This OSPKE check is not strictly necessary at runtime.
	 * But, doing it this way allows compiler optimizations
	 * if pkeys are compiled out.
	 */
	if (bad_area_access_from_pkeys(error_code, vma))
		__bad_area(regs, error_code, address, vma, SEGV_PKUERR);
	else
		__bad_area(regs, error_code, address, vma, SEGV_ACCERR);
}


__do_page_fault(struct pt_regs *regs, unsigned long error_code,
		unsigned long address)
{
	struct vm_area_struct *vma;
	struct task_struct *tsk;
	struct mm_struct *mm;
	vm_fault_t fault, major = 0;
	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
	u32 pkey;

	tsk = current;
	mm = tsk->mm;

	prefetchw(&mm->mmap_sem);

	if (unlikely(kmmio_fault(regs, address)))
		return;

	/*
	 * We fault-in kernel-space virtual memory on-demand. The
	 * 'reference' page table is init_mm.pgd.
	 *
	 * NOTE! We MUST NOT take any locks for this case. We may
	 * be in an interrupt or a critical region, and should
	 * only copy the information from the master page table,
	 * nothing more.
	 *
	 * This verifies that the fault happens in kernel space
	 * (error_code & 4) == 0, and that the fault was not a
	 * protection error (error_code & 9) == 0.
	 */
	if (unlikely(fault_in_kernel_space(address))) {
		if (!(error_code & (X86_PF_RSVD | X86_PF_USER | X86_PF_PROT))) {
			if (vmalloc_fault(address) >= 0)
				return;
		}

		/* Can handle a stale RO->RW TLB: */
		if (spurious_fault(error_code, address))
			return;

		/* kprobes don't want to hook the spurious faults: */
		if (kprobes_fault(regs))
			return;
		/*
		 * Don't take the mm semaphore here. If we fixup a prefetch
		 * fault we could otherwise deadlock:
		 */
		bad_area_nosemaphore(regs, error_code, address, NULL);

		return;
	}

	/* kprobes don't want to hook the spurious faults: */
	if (unlikely(kprobes_fault(regs)))
		return;

	if (unlikely(error_code & X86_PF_RSVD))
		pgtable_bad(regs, error_code, address);

	if (unlikely(smap_violation(error_code, regs))) {
		bad_area_nosemaphore(regs, error_code, address, NULL);
		return;
	}

	/*
	 * If we're in an interrupt, have no user context or are running
	 * in a region with pagefaults disabled then we must not take the fault
	 */
	if (unlikely(faulthandler_disabled() || !mm)) {
		bad_area_nosemaphore(regs, error_code, address, NULL);
		return;
	}

	/*
	 * It's safe to allow irq's after cr2 has been saved and the
	 * vmalloc fault has been handled.
	 *
	 * User-mode registers count as a user access even for any
	 * potential system fault or CPU buglet:
	 */
	if (user_mode(regs)) {
		local_irq_enable();
		error_code |= X86_PF_USER;
		flags |= FAULT_FLAG_USER;
	} else {
		if (regs->flags & X86_EFLAGS_IF)
			local_irq_enable();
	}

	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);

	if (error_code & X86_PF_WRITE)
		flags |= FAULT_FLAG_WRITE;
	if (error_code & X86_PF_INSTR)
		flags |= FAULT_FLAG_INSTRUCTION;

	/*
	 * When running in the kernel we expect faults to occur only to
	 * addresses in user space.  All other faults represent errors in
	 * the kernel and should generate an OOPS.  Unfortunately, in the
	 * case of an erroneous fault occurring in a code path which already
	 * holds mmap_sem we will deadlock attempting to validate the fault
	 * against the address space.  Luckily the kernel only validly
	 * references user space from well defined areas of code, which are
	 * listed in the exceptions table.
	 *
	 * As the vast majority of faults will be valid we will only perform
	 * the source reference check when there is a possibility of a
	 * deadlock. Attempt to lock the address space, if we cannot we then
	 * validate the source. If this is invalid we can skip the address
	 * space check, thus avoiding the deadlock:
	 */
	if (unlikely(!down_read_trylock(&mm->mmap_sem))) {
		if (!(error_code & X86_PF_USER) &&
		    !search_exception_tables(regs->ip)) {
			bad_area_nosemaphore(regs, error_code, address, NULL);
			return;
		}
retry:
		down_read(&mm->mmap_sem);
	} else {
		/*
		 * The above down_read_trylock() might have succeeded in
		 * which case we'll have missed the might_sleep() from
		 * down_read():
		 */
		might_sleep();
	}

	vma = find_vma(mm, address);
	if (unlikely(!vma)) {
		bad_area(regs, error_code, address);
		return;
	}
	if (likely(vma->vm_start <= address))
		goto good_area;
	if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) {
		bad_area(regs, error_code, address);
		return;
	}
	if (error_code & X86_PF_USER) {
		/*
		 * Accessing the stack below %sp is always a bug.
		 * The large cushion allows instructions like enter
		 * and pusha to work. ("enter $65535, $31" pushes
		 * 32 pointers and then decrements %sp by 65535.)
		 */
		if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
			bad_area(regs, error_code, address);
			return;
		}
	}
	if (unlikely(expand_stack(vma, address))) {
		bad_area(regs, error_code, address);
		return;
	}

	/*
	 * Ok, we have a good vm_area for this memory access, so
	 * we can handle it..
	 */
good_area:
	if (unlikely(access_error(error_code, vma))) {
		bad_area_access_error(regs, error_code, address, vma);
		return;
	}

	/*
	 * If for any reason at all we couldn't handle the fault,
	 * make sure we exit gracefully rather than endlessly redo
	 * the fault.  Since we never set FAULT_FLAG_RETRY_NOWAIT, if
	 * we get VM_FAULT_RETRY back, the mmap_sem has been unlocked.
	 *
	 * Note that handle_userfault() may also release and reacquire mmap_sem
	 * (and not return with VM_FAULT_RETRY), when returning to userland to
	 * repeat the page fault later with a VM_FAULT_NOPAGE retval
	 * (potentially after handling any pending signal during the return to
	 * userland). The return to userland is identified whenever
	 * FAULT_FLAG_USER|FAULT_FLAG_KILLABLE are both set in flags.
	 * Thus we have to be careful about not touching vma after handling the
	 * fault, so we read the pkey beforehand.
	 */
	pkey = vma_pkey(vma);
	fault = handle_mm_fault(vma, address, flags);
	major |= fault & VM_FAULT_MAJOR;

	/*
	 * If we need to retry the mmap_sem has already been released,
	 * and if there is a fatal signal pending there is no guarantee
	 * that we made any progress. Handle this case first.
	 */
	if (unlikely(fault & VM_FAULT_RETRY)) {
		/* Retry at most once */
		if (flags & FAULT_FLAG_ALLOW_RETRY) {
			flags &= ~FAULT_FLAG_ALLOW_RETRY;
			flags |= FAULT_FLAG_TRIED;
			if (!fatal_signal_pending(tsk))
				goto retry;
		}

		/* User mode? Just return to handle the fatal exception */
		if (flags & FAULT_FLAG_USER)
			return;

		/* Not returning to user mode? Handle exceptions or die: */
		no_context(regs, error_code, address, SIGBUS, BUS_ADRERR);
		return;
	}

	up_read(&mm->mmap_sem);
	if (unlikely(fault & VM_FAULT_ERROR)) {
		mm_fault_error(regs, error_code, address, &pkey, fault);
		return;
	}

	/*
	 * Major/minor page fault accounting. If any of the events
	 * returned VM_FAULT_MAJOR, we account it as a major fault.
	 */
	if (major) {
		tsk->maj_flt++;
		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
	} else {
		tsk->min_flt++;
		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
	}

	check_v8086_mode(regs, address, tsk);
}


static size_t rtnl_link_get_af_size(const struct net_device *dev,
				    u32 ext_filter_mask)
{
	struct rtnl_af_ops *af_ops;
	size_t size;

	/* IFLA_AF_SPEC */
	size = nla_total_size(sizeof(struct nlattr));

	rcu_read_lock();
	list_for_each_entry_rcu(af_ops, &rtnl_af_ops, list) {
		if (af_ops->get_link_af_size) {
			/* AF_* + nested data */
			size += nla_total_size(sizeof(struct nlattr)) +
				af_ops->get_link_af_size(dev, ext_filter_mask);
		}
	}
	rcu_read_unlock();

	return size;
}


static bool rtnl_have_link_slave_info(const struct net_device *dev)
{
	struct net_device *master_dev;
	bool ret = false;

	rcu_read_lock();

	master_dev = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
	if (master_dev && master_dev->rtnl_link_ops)
		ret = true;
	rcu_read_unlock();
	return ret;
}


struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
				       unsigned int change,
				       u32 event, gfp_t flags, int *new_nsid)
{
	struct net *net = dev_net(dev);
	struct sk_buff *skb;
	int err = -ENOBUFS;
	size_t if_info_size;

	skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), flags);
	if (skb == NULL)
		goto errout;

	err = rtnl_fill_ifinfo(skb, dev, dev_net(dev),
			       type, 0, 0, change, 0, 0, event,
			       new_nsid, -1);
	if (err < 0) {
		/* -EMSGSIZE implies BUG in if_nlmsg_size() */
		WARN_ON(err == -EMSGSIZE);
		kfree_skb(skb);
		goto errout;
	}
	return skb;
errout:
	if (err < 0)
		rtnl_set_sk_err(net, RTNLGRP_LINK, err);
	return NULL;
}


static bool stats_attr_valid(unsigned int mask, int attrid, int idxattr)
{
	return (mask & IFLA_STATS_FILTER_BIT(attrid)) &&
	       (!idxattr || idxattr == attrid);
}


static inline size_t rtnl_fdb_nlmsg_size(void)
{
	return NLMSG_ALIGN(sizeof(struct ndmsg)) +
	       nla_total_size(ETH_ALEN) +	/* NDA_LLADDR */
	       nla_total_size(sizeof(u16)) +	/* NDA_VLAN */
	       0;
}


static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
			       struct netlink_ext_ack *extack)
{
	struct net *net = sock_net(skb->sk);
	struct ifinfomsg *ifm;
	struct net_device *dev;
	struct nlattr *br_spec, *attr = NULL;
	int rem, err = -EOPNOTSUPP;
	u16 flags = 0;
	bool have_flags = false;

	if (nlmsg_len(nlh) < sizeof(*ifm))
		return -EINVAL;

	ifm = nlmsg_data(nlh);
	if (ifm->ifi_family != AF_BRIDGE)
		return -EPFNOSUPPORT;

	dev = __dev_get_by_index(net, ifm->ifi_index);
	if (!dev) {
		NL_SET_ERR_MSG(extack, "unknown ifindex");
		return -ENODEV;
	}

	br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
	if (br_spec) {
		nla_for_each_nested(attr, br_spec, rem) {
			if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
				if (nla_len(attr) < sizeof(flags))
					return -EINVAL;

				have_flags = true;
				flags = nla_get_u16(attr);
				break;
			}
		}
	}

	if (!flags || (flags & BRIDGE_FLAGS_MASTER)) {
		struct net_device *br_dev = netdev_master_upper_dev_get(dev);

		if (!br_dev || !br_dev->netdev_ops->ndo_bridge_dellink) {
			err = -EOPNOTSUPP;
			goto out;
		}

		err = br_dev->netdev_ops->ndo_bridge_dellink(dev, nlh, flags);
		if (err)
			goto out;

		flags &= ~BRIDGE_FLAGS_MASTER;
	}

	if ((flags & BRIDGE_FLAGS_SELF)) {
		if (!dev->netdev_ops->ndo_bridge_dellink)
			err = -EOPNOTSUPP;
		else
			err = dev->netdev_ops->ndo_bridge_dellink(dev, nlh,
								  flags);

		if (!err) {
			flags &= ~BRIDGE_FLAGS_SELF;

			/* Generate event to notify upper layer of bridge
			 * change
			 */
			err = rtnl_bridge_notify(dev);
		}
	}

	if (have_flags)
		memcpy(nla_data(attr), &flags, sizeof(flags));
out:
	return err;
}


void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) {
	int j;

	if (field->physical) {
		tab(n, f);
		seq_printf(f, "Physical(");
		hid_resolv_usage(field->physical, f); seq_printf(f, ")\n");
	}
	if (field->logical) {
		tab(n, f);
		seq_printf(f, "Logical(");
		hid_resolv_usage(field->logical, f); seq_printf(f, ")\n");
	}
	if (field->application) {
		tab(n, f);
		seq_printf(f, "Application(");
		hid_resolv_usage(field->application, f); seq_printf(f, ")\n");
	}
	tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage);
	for (j = 0; j < field->maxusage; j++) {
		tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n");
	}
	if (field->logical_minimum != field->logical_maximum) {
		tab(n, f); seq_printf(f, "Logical Minimum(%d)\n", field->logical_minimum);
		tab(n, f); seq_printf(f, "Logical Maximum(%d)\n", field->logical_maximum);
	}
	if (field->physical_minimum != field->physical_maximum) {
		tab(n, f); seq_printf(f, "Physical Minimum(%d)\n", field->physical_minimum);
		tab(n, f); seq_printf(f, "Physical Maximum(%d)\n", field->physical_maximum);
	}
	if (field->unit_exponent) {
		tab(n, f); seq_printf(f, "Unit Exponent(%d)\n", field->unit_exponent);
	}
	if (field->unit) {
		static const char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
		static const char *units[5][8] = {
			{ "None", "None", "None", "None", "None", "None", "None", "None" },
			{ "None", "Centimeter", "Gram", "Seconds", "Kelvin",     "Ampere", "Candela", "None" },
			{ "None", "Radians",    "Gram", "Seconds", "Kelvin",     "Ampere", "Candela", "None" },
			{ "None", "Inch",       "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" },
			{ "None", "Degrees",    "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" }
		};

		int i;
		int sys;
                __u32 data = field->unit;

		/* First nibble tells us which system we're in. */
		sys = data & 0xf;
		data >>= 4;

		if(sys > 4) {
			tab(n, f); seq_printf(f, "Unit(Invalid)\n");
		}
		else {
			int earlier_unit = 0;

			tab(n, f); seq_printf(f, "Unit(%s : ", systems[sys]);

			for (i=1 ; i<sizeof(__u32)*2 ; i++) {
				char nibble = data & 0xf;
				data >>= 4;
				if (nibble != 0) {
					if(earlier_unit++ > 0)
						seq_printf(f, "*");
					seq_printf(f, "%s", units[sys][i]);
					if(nibble != 1) {
						/* This is a _signed_ nibble(!) */

						int val = nibble & 0x7;
						if(nibble & 0x08)
							val = -((0x7 & ~val) +1);
						seq_printf(f, "^%d", val);
					}
				}
			}
			seq_printf(f, ")\n");
		}
	}
	tab(n, f); seq_printf(f, "Report Size(%u)\n", field->report_size);
	tab(n, f); seq_printf(f, "Report Count(%u)\n", field->report_count);
	tab(n, f); seq_printf(f, "Report Offset(%u)\n", field->report_offset);

	tab(n, f); seq_printf(f, "Flags( ");
	j = field->flags;
	seq_printf(f, "%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
	seq_printf(f, "%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
	seq_printf(f, "%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
	seq_printf(f, "%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
	seq_printf(f, "%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
	seq_printf(f, "%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPreferredState " : "");
	seq_printf(f, "%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
	seq_printf(f, "%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
	seq_printf(f, "%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
	seq_printf(f, ")\n");
}


static int hid_debug_events_open(struct inode *inode, struct file *file)
{
	int err = 0;
	struct hid_debug_list *list;
	unsigned long flags;

	if (!(list = kzalloc(sizeof(struct hid_debug_list), GFP_KERNEL))) {
		err = -ENOMEM;
		goto out;
	}

	if (!(list->hid_debug_buf = kzalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_KERNEL))) {
		err = -ENOMEM;
		kfree(list);
		goto out;
	}
	list->hdev = (struct hid_device *) inode->i_private;
	file->private_data = list;
	mutex_init(&list->read_mutex);

	spin_lock_irqsave(&list->hdev->debug_list_lock, flags);
	list_add_tail(&list->node, &list->hdev->debug_list);
	spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags);

out:
	return err;
}


static int pppol2tp_tunnel_ioctl(struct l2tp_tunnel *tunnel,
				 unsigned int cmd, unsigned long arg)
{
	int err = 0;
	struct sock *sk;
	struct pppol2tp_ioc_stats stats;

	l2tp_dbg(tunnel, L2TP_MSG_CONTROL,
		 "%s: pppol2tp_tunnel_ioctl(cmd=%#x, arg=%#lx)\n",
		 tunnel->name, cmd, arg);

	sk = tunnel->sock;
	sock_hold(sk);

	switch (cmd) {
	case PPPIOCGL2TPSTATS:
		err = -ENXIO;
		if (!(sk->sk_state & PPPOX_CONNECTED))
			break;

		if (copy_from_user(&stats, (void __user *) arg,
				   sizeof(stats))) {
			err = -EFAULT;
			break;
		}
		if (stats.session_id != 0) {
			/* resend to session ioctl handler */
			struct l2tp_session *session =
				l2tp_session_get(sock_net(sk), tunnel,
						 stats.session_id, true);

			if (session) {
				err = pppol2tp_session_ioctl(session, cmd,
							     arg);
				if (session->deref)
					session->deref(session);
				l2tp_session_dec_refcount(session);
			} else {
				err = -EBADR;
			}
			break;
		}
#ifdef CONFIG_XFRM
		stats.using_ipsec = (sk->sk_policy[0] || sk->sk_policy[1]) ? 1 : 0;
#endif
		pppol2tp_copy_stats(&stats, &tunnel->stats);
		if (copy_to_user((void __user *) arg, &stats, sizeof(stats))) {
			err = -EFAULT;
			break;
		}
		l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: get L2TP stats\n",
			  tunnel->name);
		err = 0;
		break;

	default:
		err = -ENOSYS;
		break;
	}

	sock_put(sk);

	return err;
}


static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
			    size_t total_len)
{
	struct sock *sk = sock->sk;
	struct sk_buff *skb;
	int error;
	struct l2tp_session *session;
	struct l2tp_tunnel *tunnel;
	struct pppol2tp_session *ps;
	int uhlen;

	error = -ENOTCONN;
	if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
		goto error;

	/* Get session and tunnel contexts */
	error = -EBADF;
	session = pppol2tp_sock_to_session(sk);
	if (session == NULL)
		goto error;

	ps = l2tp_session_priv(session);
	tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
	if (tunnel == NULL)
		goto error_put_sess;

	uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;

	/* Allocate a socket buffer */
	error = -ENOMEM;
	skb = sock_wmalloc(sk, NET_SKB_PAD + sizeof(struct iphdr) +
			   uhlen + session->hdr_len +
			   2 + total_len, /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */
			   0, GFP_KERNEL);
	if (!skb)
		goto error_put_sess_tun;

	/* Reserve space for headers. */
	skb_reserve(skb, NET_SKB_PAD);
	skb_reset_network_header(skb);
	skb_reserve(skb, sizeof(struct iphdr));
	skb_reset_transport_header(skb);
	skb_reserve(skb, uhlen);

	/* Add PPP header */
	skb->data[0] = PPP_ALLSTATIONS;
	skb->data[1] = PPP_UI;
	skb_put(skb, 2);

	/* Copy user data into skb */
	error = memcpy_from_msg(skb_put(skb, total_len), m, total_len);
	if (error < 0) {
		kfree_skb(skb);
		goto error_put_sess_tun;
	}

	local_bh_disable();
	l2tp_xmit_skb(session, skb, session->hdr_len);
	local_bh_enable();

	sock_put(ps->tunnel_sock);
	sock_put(sk);

	return total_len;

error_put_sess_tun:
	sock_put(ps->tunnel_sock);
error_put_sess:
	sock_put(sk);
error:
	return error;
}


static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
				struct l2tp_session *session,
				struct net_device *dev)
{
	unsigned int overhead = 0;
	struct dst_entry *dst;
	u32 l3_overhead = 0;

	/* if the encap is UDP, account for UDP header size */
	if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
		overhead += sizeof(struct udphdr);
		dev->needed_headroom += sizeof(struct udphdr);
	}
	if (session->mtu != 0) {
		dev->mtu = session->mtu;
		dev->needed_headroom += session->hdr_len;
		return;
	}
	lock_sock(tunnel->sock);
	l3_overhead = kernel_sock_ip_overhead(tunnel->sock);
	release_sock(tunnel->sock);
	if (l3_overhead == 0) {
		/* L3 Overhead couldn't be identified, this could be
		 * because tunnel->sock was NULL or the socket's
		 * address family was not IPv4 or IPv6,
		 * dev mtu stays at 1500.
		 */
		return;
	}
	/* Adjust MTU, factor overhead - underlay L3, overlay L2 hdr
	 * UDP overhead, if any, was already factored in above.
	 */
	overhead += session->hdr_len + ETH_HLEN + l3_overhead;

	/* If PMTU discovery was enabled, use discovered MTU on L2TP device */
	dst = sk_dst_get(tunnel->sock);
	if (dst) {
		/* dst_mtu will use PMTU if found, else fallback to intf MTU */
		u32 pmtu = dst_mtu(dst);

		if (pmtu != 0)
			dev->mtu = pmtu;
		dst_release(dst);
	}
	session->mtu = dev->mtu - overhead;
	dev->mtu = session->mtu;
	dev->needed_headroom += session->hdr_len;
}


static int __init l2tp_nl_init(void)
{
	pr_info("L2TP netlink interface\n");
	return genl_register_family(&l2tp_nl_family);
}


float IIR2_filter::update(float x)
{
    prev[0] = x;
    double y = x * coeffs[0];

    for (int i = 4; i >= 1; i--)
    {
        y += coeffs[i] * prev[i];
        prev[i] = prev[i - 1];
    }

    prev[3] = y;
    return (float)y;
}


    static void _SaveDebugData(const char *name, const float *data, int minpos, int maxpos, double coeff)
    {
        FILE *fptr = fopen(name, "wt");
        int i;

        if (fptr)
        {
            printf("\nWriting BPM debug data into file %s\n", name);
            for (i = minpos; i < maxpos; i ++)
            {
                fprintf(fptr, "%d\t%.1lf\t%f\n", i, coeff / (double)i, data[i]);
            }
            fclose(fptr);
        }
    }


void MAFilter(float *dest, const float *source, int start, int end, int N)
{
    for (int i = start; i < end; i++)
    {
        int i1 = i - N / 2;
        int i2 = i + N / 2 + 1;
        if (i1 < start) i1 = start;
        if (i2 > end)   i2 = end;

        double sum = 0;
        for (int j = i1; j < i2; j ++)
        {
            sum += source[j];
        }
        dest[i] = (float)(sum / (i2 - i1));
    }
}


struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
			    struct ovl_entry *oe)
{
	struct inode *inode;

	inode = new_inode(sb);
	if (!inode)
		return NULL;

	inode->i_ino = get_next_ino();
	inode->i_mode = mode;
	inode->i_flags |= S_NOATIME | S_NOCMTIME;
	inode->i_private = oe;

	mode &= S_IFMT;
	switch (mode) {
	case S_IFDIR:
		inode->i_op = &ovl_dir_inode_operations;
		inode->i_fop = &ovl_dir_operations;
		break;

	case S_IFLNK:
		inode->i_op = &ovl_symlink_inode_operations;
		break;

	case S_IFREG:
	case S_IFSOCK:
	case S_IFBLK:
	case S_IFCHR:
	case S_IFIFO:
		inode->i_op = &ovl_file_inode_operations;
		break;

	default:
		WARN(1, "illegal file type: %i\n", mode);
		iput(inode);
		inode = NULL;
	}

	return inode;
}


ofputil_decode_ofp11_port(struct ofputil_phy_port *pp,
                          const struct ofp11_port *op)
{
    enum ofperr error;

    error = ofputil_port_from_ofp11(op->port_no, &pp->port_no);
    if (error) {
        return error;
    }
    pp->hw_addr = op->hw_addr;
    ovs_strlcpy(pp->name, op->name, OFP_MAX_PORT_NAME_LEN);

    pp->config = ntohl(op->config) & OFPPC11_ALL;
    pp->state = ntohl(op->state) & OFPPS11_ALL;

    pp->curr = netdev_port_features_from_ofp11(op->curr);
    pp->advertised = netdev_port_features_from_ofp11(op->advertised);
    pp->supported = netdev_port_features_from_ofp11(op->supported);
    pp->peer = netdev_port_features_from_ofp11(op->peer);

    pp->curr_speed = ntohl(op->curr_speed);
    pp->max_speed = ntohl(op->max_speed);

    return 0;
}


ofputil_match_to_ofp11_match(const struct match *match,
                             struct ofp11_match *ofmatch)
{
    uint32_t wc = 0;

    memset(ofmatch, 0, sizeof *ofmatch);
    ofmatch->omh.type = htons(OFPMT_STANDARD);
    ofmatch->omh.length = htons(OFPMT11_STANDARD_LENGTH);

    if (!match->wc.masks.in_port.ofp_port) {
        wc |= OFPFW11_IN_PORT;
    } else {
        ofmatch->in_port = ofputil_port_to_ofp11(match->flow.in_port.ofp_port);
    }

    ofmatch->dl_src = match->flow.dl_src;
    ofmatch->dl_src_mask = eth_addr_invert(match->wc.masks.dl_src);
    ofmatch->dl_dst = match->flow.dl_dst;
    ofmatch->dl_dst_mask = eth_addr_invert(match->wc.masks.dl_dst);

    if (match->wc.masks.vlan_tci == htons(0)) {
        wc |= OFPFW11_DL_VLAN | OFPFW11_DL_VLAN_PCP;
    } else if (match->wc.masks.vlan_tci & htons(VLAN_CFI)
               && !(match->flow.vlan_tci & htons(VLAN_CFI))) {
        ofmatch->dl_vlan = htons(OFPVID11_NONE);
        wc |= OFPFW11_DL_VLAN_PCP;
    } else {
        if (!(match->wc.masks.vlan_tci & htons(VLAN_VID_MASK))) {
            ofmatch->dl_vlan = htons(OFPVID11_ANY);
        } else {
            ofmatch->dl_vlan = htons(vlan_tci_to_vid(match->flow.vlan_tci));
        }

        if (!(match->wc.masks.vlan_tci & htons(VLAN_PCP_MASK))) {
            wc |= OFPFW11_DL_VLAN_PCP;
        } else {
            ofmatch->dl_vlan_pcp = vlan_tci_to_pcp(match->flow.vlan_tci);
        }
    }

    if (!match->wc.masks.dl_type) {
        wc |= OFPFW11_DL_TYPE;
    } else {
        ofmatch->dl_type = ofputil_dl_type_to_openflow(match->flow.dl_type);
    }

    if (!(match->wc.masks.nw_tos & IP_DSCP_MASK)) {
        wc |= OFPFW11_NW_TOS;
    } else {
        ofmatch->nw_tos = match->flow.nw_tos & IP_DSCP_MASK;
    }

    if (!match->wc.masks.nw_proto) {
        wc |= OFPFW11_NW_PROTO;
    } else {
        ofmatch->nw_proto = match->flow.nw_proto;
    }

    ofmatch->nw_src = match->flow.nw_src;
    ofmatch->nw_src_mask = ~match->wc.masks.nw_src;
    ofmatch->nw_dst = match->flow.nw_dst;
    ofmatch->nw_dst_mask = ~match->wc.masks.nw_dst;

    if (!match->wc.masks.tp_src) {
        wc |= OFPFW11_TP_SRC;
    } else {
        ofmatch->tp_src = match->flow.tp_src;
    }

    if (!match->wc.masks.tp_dst) {
        wc |= OFPFW11_TP_DST;
    } else {
        ofmatch->tp_dst = match->flow.tp_dst;
    }

    if (!(match->wc.masks.mpls_lse[0] & htonl(MPLS_LABEL_MASK))) {
        wc |= OFPFW11_MPLS_LABEL;
    } else {
        ofmatch->mpls_label = htonl(mpls_lse_to_label(
                                        match->flow.mpls_lse[0]));
    }

    if (!(match->wc.masks.mpls_lse[0] & htonl(MPLS_TC_MASK))) {
        wc |= OFPFW11_MPLS_TC;
    } else {
        ofmatch->mpls_tc = mpls_lse_to_tc(match->flow.mpls_lse[0]);
    }

    ofmatch->metadata = match->flow.metadata;
    ofmatch->metadata_mask = ~match->wc.masks.metadata;

    ofmatch->wildcards = htonl(wc);
}


ofputil_pull_ofp14_port_stats(struct ofputil_port_stats *ops,
                              struct ofpbuf *msg)
{
    const struct ofp14_port_stats *ps14 = ofpbuf_try_pull(msg, sizeof *ps14);
    if (!ps14) {
        return OFPERR_OFPBRC_BAD_LEN;
    }

    size_t len = ntohs(ps14->length);
    if (len < sizeof *ps14 || len - sizeof *ps14 > msg->size) {
        return OFPERR_OFPBRC_BAD_LEN;
    }
    len -= sizeof *ps14;

    enum ofperr error = ofputil_port_from_ofp11(ps14->port_no, &ops->port_no);
    if (error) {
        return error;
    }

    ops->duration_sec = ntohl(ps14->duration_sec);
    ops->duration_nsec = ntohl(ps14->duration_nsec);
    ops->stats.rx_packets = ntohll(ps14->rx_packets);
    ops->stats.tx_packets = ntohll(ps14->tx_packets);
    ops->stats.rx_bytes = ntohll(ps14->rx_bytes);
    ops->stats.tx_bytes = ntohll(ps14->tx_bytes);
    ops->stats.rx_dropped = ntohll(ps14->rx_dropped);
    ops->stats.tx_dropped = ntohll(ps14->tx_dropped);
    ops->stats.rx_errors = ntohll(ps14->rx_errors);
    ops->stats.tx_errors = ntohll(ps14->tx_errors);

    struct ofpbuf properties = ofpbuf_const_initializer(ofpbuf_pull(msg, len),
                                                        len);
    while (properties.size > 0) {
        struct ofpbuf payload;
        enum ofperr error;
        uint64_t type = 0;

        error = ofpprop_pull(&properties, &payload, &type);
        if (error) {
            return error;
        }
        switch (type) {
        case OFPPSPT14_ETHERNET:
            error = parse_ofp14_port_stats_ethernet_property(&payload, ops);
            break;
        case OFPPROP_EXP(INTEL_VENDOR_ID, INTEL_PORT_STATS_RFC2819):
            error = parse_intel_port_stats_property(&payload,
                                                    INTEL_PORT_STATS_RFC2819,
                                                    ops);
            break;
        default:
            error = OFPPROP_UNKNOWN(true, "port stats", type);
            break;
        }

        if (error) {
            return error;
        }
    }

    return 0;
}


format_CONJUNCTION(const struct ofpact_conjunction *oc, struct ds *s)
{
    ds_put_format(s, "%sconjunction(%s%"PRIu32",%"PRIu8"/%"PRIu8"%s)%s",
                  colors.paren, colors.end,
                  oc->id, oc->clause + 1, oc->n_clauses,
                  colors.paren, colors.end);
}


format_SET_FIELD(const struct ofpact_set_field *a, struct ds *s)
{
    if (a->ofpact.raw == NXAST_RAW_REG_LOAD) {
        struct mf_subfield dst;
        uint64_t value;

        dst.ofs = dst.n_bits = 0;
        while (next_load_segment(a, &dst, &value)) {
            ds_put_format(s, "%sload:%s%#"PRIx64"%s->%s",
                          colors.special, colors.end, value,
                          colors.special, colors.end);
            mf_format_subfield(&dst, s);
            ds_put_char(s, ',');
        }
        ds_chomp(s, ',');
    } else {
        ds_put_format(s, "%sset_field:%s", colors.special, colors.end);
        mf_format(a->field, a->value, ofpact_set_field_mask(a), s);
        ds_put_format(s, "%s->%s%s",
                      colors.special, colors.end, a->field->name);
    }
}


parse_NOTE(const char *arg, struct ofpbuf *ofpacts,
           enum ofputil_protocol *usable_protocols OVS_UNUSED)
{
    size_t start_ofs = ofpacts->size;
    ofpact_put_NOTE(ofpacts);
    arg = ofpbuf_put_hex(ofpacts, arg, NULL);
    if (arg[0]) {
        return xstrdup("bad hex digit in `note' argument");
    }
    struct ofpact_note *note = ofpbuf_at_assert(ofpacts, start_ofs,
                                                sizeof *note);
    note->length = ofpacts->size - (start_ofs + sizeof *note);
    ofpact_finish_NOTE(ofpacts, &note);
    return NULL;
}


format_NAT(const struct ofpact_nat *a, struct ds *ds)
{
    ds_put_format(ds, "%snat%s", colors.paren, colors.end);

    if (a->flags & (NX_NAT_F_SRC | NX_NAT_F_DST)) {
        ds_put_format(ds, "%s(%s", colors.paren, colors.end);
        ds_put_format(ds, a->flags & NX_NAT_F_SRC ? "%ssrc%s" : "%sdst%s",
                      colors.param, colors.end);

        if (a->range_af != AF_UNSPEC) {
            ds_put_format(ds, "%s=%s", colors.param, colors.end);

            if (a->range_af == AF_INET) {
                ds_put_format(ds, IP_FMT, IP_ARGS(a->range.addr.ipv4.min));

                if (a->range.addr.ipv4.max
                    && a->range.addr.ipv4.max != a->range.addr.ipv4.min) {
                    ds_put_format(ds, "-"IP_FMT,
                                  IP_ARGS(a->range.addr.ipv4.max));
                }
            } else if (a->range_af == AF_INET6) {
                ipv6_format_addr_bracket(&a->range.addr.ipv6.min, ds,
                                        a->range.proto.min);

                if (!ipv6_mask_is_any(&a->range.addr.ipv6.max)
                    && memcmp(&a->range.addr.ipv6.max, &a->range.addr.ipv6.min,
                              sizeof(struct in6_addr)) != 0) {
                    ds_put_char(ds, '-');
                    ipv6_format_addr_bracket(&a->range.addr.ipv6.max, ds,
                                            a->range.proto.min);
                }
            }
            if (a->range.proto.min) {
                ds_put_char(ds, ':');
                ds_put_format(ds, "%"PRIu16, a->range.proto.min);

                if (a->range.proto.max
                    && a->range.proto.max != a->range.proto.min) {
                    ds_put_format(ds, "-%"PRIu16, a->range.proto.max);
                }
            }
            ds_put_char(ds, ',');

            if (a->flags & NX_NAT_F_PERSISTENT) {
                ds_put_format(ds, "%spersistent%s,",
                              colors.value, colors.end);
            }
            if (a->flags & NX_NAT_F_PROTO_HASH) {
                ds_put_format(ds, "%shash%s,", colors.value, colors.end);
            }
            if (a->flags & NX_NAT_F_PROTO_RANDOM) {
                ds_put_format(ds, "%srandom%s,", colors.value, colors.end);
            }
        }
        ds_chomp(ds, ',');
        ds_put_format(ds, "%s)%s", colors.paren, colors.end);
    }
}


parse_CLONE(char *arg, struct ofpbuf *ofpacts,
             enum ofputil_protocol *usable_protocols)
{
    const size_t clone_offset = ofpacts_pull(ofpacts);
    struct ofpact_nest *clone = ofpact_put_CLONE(ofpacts);
    char *error;

    ofpbuf_pull(ofpacts, sizeof *clone);
    error = ofpacts_parse_copy(arg, ofpacts, usable_protocols, false, 0);
    /* header points to the action list */
    ofpacts->header = ofpbuf_push_uninit(ofpacts, sizeof *clone);
    clone = ofpacts->header;

    ofpact_finish_CLONE(ofpacts, &clone);
    ofpbuf_push_uninit(ofpacts, clone_offset);
    return error;
}


format_SET_MPLS_TTL(const struct ofpact_mpls_ttl *a, struct ds *s)
{
    ds_put_format(s, "%sset_mpls_ttl(%s%"PRIu8"%s)%s",
                  colors.paren, colors.end, a->ttl,
                  colors.paren, colors.end);
}


parse_OUTPUT_TRUNC(const char *arg, struct ofpbuf *ofpacts OVS_UNUSED,
                 enum ofputil_protocol *usable_protocols OVS_UNUSED)
{
    /* Disable output_trunc parsing.  Expose as output(port=N,max_len=M) and
     * reuse parse_OUTPUT to parse output_trunc action. */
    return xasprintf("unknown action %s", arg);
}


parse_SET_MPLS_LABEL(char *arg, struct ofpbuf *ofpacts,
                     enum ofputil_protocol *usable_protocols OVS_UNUSED)
{
    struct ofpact_mpls_label *mpls_label = ofpact_put_SET_MPLS_LABEL(ofpacts);
    if (*arg == '\0') {
        return xstrdup("set_mpls_label: expected label.");
    }

    mpls_label->label = htonl(atoi(arg));
    return NULL;
}


format_OUTPUT(const struct ofpact_output *a, struct ds *s)
{
    if (ofp_to_u16(a->port) < ofp_to_u16(OFPP_MAX)) {
        ds_put_format(s, "%soutput:%s%"PRIu32,
                      colors.special, colors.end, a->port);
    } else {
        ofputil_format_port(a->port, s);
        if (a->port == OFPP_CONTROLLER) {
            ds_put_format(s, ":%"PRIu16, a->max_len);
        }
    }
}


format_OUTPUT_REG(const struct ofpact_output_reg *a, struct ds *s)
{
    ds_put_format(s, "%soutput:%s", colors.special, colors.end);
    mf_format_subfield(&a->src, s);
}


format_CT_CLEAR(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
{
    ds_put_format(s, "%sct_clear%s", colors.value, colors.end);
}


static void h2_session_ev_remote_goaway(h2_session *session, int arg, const char *msg)
{
    if (!session->remote.shutdown) {
        session->remote.error = arg;
        session->remote.accepting = 0;
        session->remote.shutdown = 1;
        cleanup_unprocessed_streams(session);
        update_child_status(session, SERVER_CLOSING, "remote goaway");
        transit(session, "remote goaway", H2_SESSION_ST_DONE);
    }
}


static void h2_session_ev_conn_timeout(h2_session *session, int arg, const char *msg)
{
    transit(session, msg, H2_SESSION_ST_DONE);
    if (!session->local.shutdown) {
        h2_session_shutdown(session, arg, msg, 1);
    }
}


static int on_begin_headers_cb(nghttp2_session *ngh2,
                               const nghttp2_frame *frame, void *userp)
{
    h2_session *session = (h2_session *)userp;
    h2_stream *s;

    /* We may see HEADERs at the start of a stream or after all DATA
     * streams to carry trailers. */
    (void)ngh2;
    s = h2_session_stream_get(session, frame->hd.stream_id);
    if (s) {
        /* nop */
    }
    else {
        s = h2_session_open_stream(userp, frame->hd.stream_id, 0);
    }
    return s? 0 : NGHTTP2_ERR_START_STREAM_NOT_ALLOWED;
}


    CiffDirectory::~CiffDirectory()
    {
        Components::iterator b = components_.begin();
        Components::iterator e = components_.end();
        for (Components::iterator i = b; i != e; ++i) {
            delete *i;
        }
    }


    uint32_t CiffComponent::writeValueData(Blob& blob, uint32_t offset)
    {
        if (dataLocation() == valueData) {
#ifdef DEBUG
            std::cout << "  Data for tag 0x" << std::hex << tagId()
                      << ", " << std::dec << size_ << " Bytes\n";
#endif
            offset_ = offset;
            append(blob, pData_, size_);
            offset += size_;
            // Pad the value to an even number of bytes
            if (size_ % 2 == 1) {
                blob.push_back(0);
                ++offset;
            }
        }
        return offset;
    } // CiffComponent::writeValueData


    void CrwMap::decode0x080a(const CiffComponent& ciffComponent,
                              const CrwMapping*    /*pCrwMapping*/,
                                    Image&         image,
                                    ByteOrder      byteOrder)
    {
        if (ciffComponent.typeId() != asciiString) return;

        // Make
        ExifKey key1("Exif.Image.Make");
        Value::AutoPtr value1 = Value::create(ciffComponent.typeId());
        uint32_t i = 0;
        for (;    i < ciffComponent.size()
               && ciffComponent.pData()[i] != '\0'; ++i) {
            // empty
        }
        value1->read(ciffComponent.pData(), ++i, byteOrder);
        image.exifData().add(key1, value1.get());

        // Model
        ExifKey key2("Exif.Image.Model");
        Value::AutoPtr value2 = Value::create(ciffComponent.typeId());
        uint32_t j = i;
        for (;    i < ciffComponent.size()
               && ciffComponent.pData()[i] != '\0'; ++i) {
            // empty
        }
        value2->read(ciffComponent.pData() + j, i - j + 1, byteOrder);
        image.exifData().add(key2, value2.get());
    } // CrwMap::decode0x080a


    CiffComponent::~CiffComponent()
    {
        if (isAllocated_) delete[] pData_;
    }


    bool CiffComponent::doEmpty() const
    {
        return size_ == 0;
    }


    void CiffDirectory::doRead(const byte* pData,
                               uint32_t    size,
                               uint32_t    start,
                               ByteOrder   byteOrder)
    {
        CiffComponent::doRead(pData, size, start, byteOrder);
#ifdef DEBUG
        std::cout << "Reading directory 0x" << std::hex << tag() << "\n";
#endif
        readDirectory(pData + offset(), this->size(), byteOrder);
#ifdef DEBUG
        std::cout << "<---- 0x" << std::hex << tag() << "\n";
#endif
    } // CiffDirectory::doRead


    DataBuf packIfdId(const ExifData& exifData,
                            IfdId     ifdId,
                            ByteOrder byteOrder)
    {
        const uint16_t size = 1024;
        DataBuf buf(size);
        std::memset(buf.pData_, 0x0, buf.size_);

        uint16_t len = 0;
        const ExifData::const_iterator b = exifData.begin();
        const ExifData::const_iterator e = exifData.end();
        for (ExifData::const_iterator i = b; i != e; ++i) {
            if (i->ifdId() != ifdId) continue;
            const uint16_t s = i->tag()*2 + static_cast<uint16_t>(i->size());
            assert(s <= size);
            if (len < s) len = s;
            i->copy(buf.pData_ + i->tag()*2, byteOrder);
        }
        // Round the size to make it even.
        buf.size_ = len + len%2;
        return buf;
    }


    void CiffComponent::decode(Image& image, ByteOrder byteOrder) const
    {
        doDecode(image, byteOrder);
    }


    void CrwMap::decodeArray(const CiffComponent& ciffComponent,
                             const CrwMapping*    pCrwMapping,
                                   Image&         image,
                                   ByteOrder      byteOrder)
    {
        if (ciffComponent.typeId() != unsignedShort) {
            return decodeBasic(ciffComponent, pCrwMapping, image, byteOrder);
        }

        long aperture = 0;
        long shutterSpeed = 0;

        IfdId ifdId = ifdIdNotSet;
        switch (pCrwMapping->tag_) {
        case 0x0001: ifdId = canonCsId; break;
        case 0x0004: ifdId = canonSiId; break;
        case 0x000f: ifdId = canonCfId; break;
        case 0x0012: ifdId = canonPiId; break;
        }
        assert(ifdId != ifdIdNotSet);

        std::string groupName(Internal::groupName(ifdId));
        uint16_t c = 1;
        while (uint32_t(c)*2 < ciffComponent.size()) {
            uint16_t n = 1;
            ExifKey key(c, groupName);
            UShortValue value;
            if (ifdId == canonCsId && c == 23 && ciffComponent.size() > 50) n = 3;
            value.read(ciffComponent.pData() + c*2, n*2, byteOrder);
            image.exifData().add(key, &value);
            if (ifdId == canonSiId && c == 21) aperture = value.toLong();
            if (ifdId == canonSiId && c == 22) shutterSpeed = value.toLong();
            c += n;
        }

        if (ifdId == canonSiId) {
            // Exif.Photo.FNumber
            float f = fnumber(canonEv(aperture));
            Rational r = floatToRationalCast(f);
            URational ur(r.first, r.second);
            URationalValue fn;
            fn.value_.push_back(ur);
            image.exifData().add(ExifKey("Exif.Photo.FNumber"), &fn);

            // Exif.Photo.ExposureTime
            ur = exposureTime(canonEv(shutterSpeed));
            URationalValue et;
            et.value_.push_back(ur);
            image.exifData().add(ExifKey("Exif.Photo.ExposureTime"), &et);
        }
    } // CrwMap::decodeArray


static void next_submodule_warn_missing(struct submodule_update_clone *suc,
		struct strbuf *out, const char *displaypath)
{
	/*
	 * Only mention uninitialized submodules when their
	 * paths have been specified.
	 */
	if (suc->warn_if_uninitialized) {
		strbuf_addf(out,
			_("Submodule path '%s' not initialized"),
			displaypath);
		strbuf_addch(out, '\n');
		strbuf_addstr(out,
			_("Maybe you want to use 'update --init'?"));
		strbuf_addch(out, '\n');
	}
}


static int clone_submodule(const char *path, const char *gitdir, const char *url,
			   const char *depth, struct string_list *reference,
			   int quiet, int progress)
{
	struct child_process cp = CHILD_PROCESS_INIT;

	argv_array_push(&cp.args, "clone");
	argv_array_push(&cp.args, "--no-checkout");
	if (quiet)
		argv_array_push(&cp.args, "--quiet");
	if (progress)
		argv_array_push(&cp.args, "--progress");
	if (depth && *depth)
		argv_array_pushl(&cp.args, "--depth", depth, NULL);
	if (reference->nr) {
		struct string_list_item *item;
		for_each_string_list_item(item, reference)
			argv_array_pushl(&cp.args, "--reference",
					 item->string, NULL);
	}
	if (gitdir && *gitdir)
		argv_array_pushl(&cp.args, "--separate-git-dir", gitdir, NULL);

	argv_array_push(&cp.args, "--");
	argv_array_push(&cp.args, url);
	argv_array_push(&cp.args, path);

	cp.git_cmd = 1;
	prepare_submodule_repo_env(&cp.env_array);
	cp.no_stdin = 1;

	return run_command(&cp);
}


static int starts_with_dot_dot_slash(const char *str)
{
	return str[0] == '.' && str[1] == '.' && is_dir_sep(str[2]);
}


static int starts_with_dot_slash(const char *str)
{
	return str[0] == '.' && is_dir_sep(str[1]);
}


static void prepare_possible_alternates(const char *sm_name,
		struct string_list *reference)
{
	char *sm_alternate = NULL, *error_strategy = NULL;
	struct submodule_alternate_setup sas = SUBMODULE_ALTERNATE_SETUP_INIT;

	git_config_get_string("submodule.alternateLocation", &sm_alternate);
	if (!sm_alternate)
		return;

	git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);

	if (!error_strategy)
		error_strategy = xstrdup("die");

	sas.submodule_name = sm_name;
	sas.reference = reference;
	if (!strcmp(error_strategy, "die"))
		sas.error_mode = SUBMODULE_ALTERNATE_ERROR_DIE;
	else if (!strcmp(error_strategy, "info"))
		sas.error_mode = SUBMODULE_ALTERNATE_ERROR_INFO;
	else if (!strcmp(error_strategy, "ignore"))
		sas.error_mode = SUBMODULE_ALTERNATE_ERROR_IGNORE;
	else
		die(_("Value '%s' for submodule.alternateErrorStrategy is not recognized"), error_strategy);

	if (!strcmp(sm_alternate, "superproject"))
		foreach_alt_odb(add_possible_reference_from_superproject, &sas);
	else if (!strcmp(sm_alternate, "no"))
		; /* do nothing */
	else
		die(_("Value '%s' for submodule.alternateLocation is not recognized"), sm_alternate);

	free(sm_alternate);
	free(error_strategy);
}


static void init_submodule(const char *path, const char *prefix, int quiet)
{
	const struct submodule *sub;
	struct strbuf sb = STRBUF_INIT;
	char *upd = NULL, *url = NULL, *displaypath;

	/* Only loads from .gitmodules, no overlay with .git/config */
	gitmodules_config();

	if (prefix && get_super_prefix())
		die("BUG: cannot have prefix and superprefix");
	else if (prefix)
		displaypath = xstrdup(relative_path(path, prefix, &sb));
	else if (get_super_prefix()) {
		strbuf_addf(&sb, "%s%s", get_super_prefix(), path);
		displaypath = strbuf_detach(&sb, NULL);
	} else
		displaypath = xstrdup(path);

	sub = submodule_from_path(null_sha1, path);

	if (!sub)
		die(_("No url found for submodule path '%s' in .gitmodules"),
			displaypath);

	/*
	 * NEEDSWORK: In a multi-working-tree world, this needs to be
	 * set in the per-worktree config.
	 *
	 * Set active flag for the submodule being initialized
	 */
	if (!is_submodule_active(the_repository, path)) {
		strbuf_reset(&sb);
		strbuf_addf(&sb, "submodule.%s.active", sub->name);
		git_config_set_gently(sb.buf, "true");
	}

	/*
	 * Copy url setting when it is not set yet.
	 * To look up the url in .git/config, we must not fall back to
	 * .gitmodules, so look it up directly.
	 */
	strbuf_reset(&sb);
	strbuf_addf(&sb, "submodule.%s.url", sub->name);
	if (git_config_get_string(sb.buf, &url)) {
		if (!sub->url)
			die(_("No url found for submodule path '%s' in .gitmodules"),
				displaypath);

		url = xstrdup(sub->url);

		/* Possibly a url relative to parent */
		if (starts_with_dot_dot_slash(url) ||
		    starts_with_dot_slash(url)) {
			char *remoteurl, *relurl;
			char *remote = get_default_remote();
			struct strbuf remotesb = STRBUF_INIT;
			strbuf_addf(&remotesb, "remote.%s.url", remote);
			free(remote);

			if (git_config_get_string(remotesb.buf, &remoteurl)) {
				warning(_("could not lookup configuration '%s'. Assuming this repository is its own authoritative upstream."), remotesb.buf);
				remoteurl = xgetcwd();
			}
			relurl = relative_url(remoteurl, url, NULL);
			strbuf_release(&remotesb);
			free(remoteurl);
			free(url);
			url = relurl;
		}

		if (git_config_set_gently(sb.buf, url))
			die(_("Failed to register url for submodule path '%s'"),
			    displaypath);
		if (!quiet)
			fprintf(stderr,
				_("Submodule '%s' (%s) registered for path '%s'\n"),
				sub->name, url, displaypath);
	}

	/* Copy "update" setting when it is not set yet */
	strbuf_reset(&sb);
	strbuf_addf(&sb, "submodule.%s.update", sub->name);
	if (git_config_get_string(sb.buf, &upd) &&
	    sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
		if (sub->update_strategy.type == SM_UPDATE_COMMAND) {
			fprintf(stderr, _("warning: command update mode suggested for submodule '%s'\n"),
				sub->name);
			upd = xstrdup("none");
		} else
			upd = xstrdup(submodule_strategy_to_string(&sub->update_strategy));

		if (git_config_set_gently(sb.buf, upd))
			die(_("Failed to register update mode for submodule path '%s'"), displaypath);
	}
	strbuf_release(&sb);
	free(displaypath);
	free(url);
	free(upd);
}


static const struct submodule *config_from(struct submodule_cache *cache,
		const unsigned char *treeish_name, const char *key,
		enum lookup_type lookup_type)
{
	struct strbuf rev = STRBUF_INIT;
	unsigned long config_size;
	char *config = NULL;
	unsigned char sha1[20];
	enum object_type type;
	const struct submodule *submodule = NULL;
	struct parse_config_parameter parameter;

	/*
	 * If any parameter except the cache is a NULL pointer just
	 * return the first submodule. Can be used to check whether
	 * there are any submodules parsed.
	 */
	if (!treeish_name || !key) {
		struct hashmap_iter iter;
		struct submodule_entry *entry;

		entry = hashmap_iter_first(&cache->for_name, &iter);
		if (!entry)
			return NULL;
		return entry->config;
	}

	if (!gitmodule_sha1_from_commit(treeish_name, sha1, &rev))
		goto out;

	switch (lookup_type) {
	case lookup_name:
		submodule = cache_lookup_name(cache, sha1, key);
		break;
	case lookup_path:
		submodule = cache_lookup_path(cache, sha1, key);
		break;
	}
	if (submodule)
		goto out;

	config = read_sha1_file(sha1, &type, &config_size);
	if (!config || type != OBJ_BLOB)
		goto out;

	/* fill the submodule config into the cache */
	parameter.cache = cache;
	parameter.treeish_name = treeish_name;
	parameter.gitmodules_sha1 = sha1;
	parameter.overwrite = 0;
	git_config_from_mem(parse_config, CONFIG_ORIGIN_SUBMODULE_BLOB, rev.buf,
			config, config_size, &parameter);
	strbuf_release(&rev);
	free(config);

	switch (lookup_type) {
	case lookup_name:
		return cache_lookup_name(cache, sha1, key);
	case lookup_path:
		return cache_lookup_path(cache, sha1, key);
	default:
		return NULL;
	}

out:
	strbuf_release(&rev);
	free(config);
	return submodule;
}


static void submodule_cache_clear(struct submodule_cache *cache)
{
	struct hashmap_iter iter;
	struct submodule_entry *entry;

	if (!cache->initialized)
		return;

	/*
	 * We iterate over the name hash here to be symmetric with the
	 * allocation of struct submodule entries. Each is allocated by
	 * their .gitmodule blob sha1 and submodule name.
	 */
	hashmap_iter_init(&cache->for_name, &iter);
	while ((entry = hashmap_iter_next(&iter)))
		free_one_config(entry);

	hashmap_free(&cache->for_path, 1);
	hashmap_free(&cache->for_name, 1);
	cache->initialized = 0;
}


static void submodule_cache_init(struct submodule_cache *cache)
{
	hashmap_init(&cache->for_path, (hashmap_cmp_fn) config_path_cmp, NULL, 0);
	hashmap_init(&cache->for_name, (hashmap_cmp_fn) config_name_cmp, NULL, 0);
	cache->initialized = 1;
}


void qmp_netdev_del(const char *id, Error **errp)
{
    NetClientState *nc;
    QemuOpts *opts;

    nc = qemu_find_netdev(id);
    if (!nc) {
        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
                  "Device '%s' not found", id);
        return;
    }

    opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), id);
    if (!opts) {
        error_setg(errp, "Device '%s' is not a netdev", id);
        return;
    }

    qemu_del_net_client(nc);
    qemu_opts_del(opts);
}