Exemple #1
0
/**
 * seahorse_util_memory_output_length:
 * @output: a stream
 *
 * A replacement for #g_memory_output_stream_get_data_size (since 2.18)
 *
 * Returns: The length of the stream
 */
gsize
seahorse_util_memory_output_length (GMemoryOutputStream *output)
{
	GSeekable *seekable;
	goffset offset, end;
	
	/* 
	 * This is a replacement for g_memory_output_stream_get_data_size()
	 * which is not available in current version of glib.
	 */
	
	g_return_val_if_fail (G_IS_MEMORY_OUTPUT_STREAM (output), 0);
	g_return_val_if_fail (G_IS_SEEKABLE (output), 0);
	
	seekable = G_SEEKABLE (output);
	offset = g_seekable_tell (seekable);
	
	if (!g_seekable_seek (seekable, 0, G_SEEK_END, NULL, NULL))
		g_return_val_if_reached (0);
	
	end = g_seekable_tell (seekable);
	
	if (offset != end) {
		if (!g_seekable_seek (seekable, offset, G_SEEK_SET, NULL, NULL))
			g_return_val_if_reached (0);
	}
	
	return (gsize)end;
}
Exemple #2
0
/*
 * et_ogg_tell_func:
 * @datasource: the Ogg parser state
 *
 * Tell the current position of the stream from the beginning of the Ogg file.
 *
 * Returns: the current position in the Ogg file
 */
static long
et_ogg_tell_func (void *datasource)
{
    EtOggState *state = (EtOggState *)datasource;

    return g_seekable_tell (G_SEEKABLE (state->istream));
}
Exemple #3
0
static gint64
xmms_gvfs_seek (xmms_xform_t *xform, gint64 offset,
                xmms_xform_seek_mode_t whence, xmms_error_t *error)
{
    GSeekType type;
    GError *err = NULL;
    xmms_gvfs_data_t *data = xmms_xform_private_data_get (xform);

    g_return_val_if_fail (data, -1);
    g_return_val_if_fail (!g_input_stream_is_closed (data->handle), -1);

    switch (whence) {
    case XMMS_XFORM_SEEK_CUR:
        type = G_SEEK_CUR;
        break;
    case XMMS_XFORM_SEEK_SET:
        type = G_SEEK_SET;
        break;
    case XMMS_XFORM_SEEK_END:
        type = G_SEEK_END;
        break;
    }

    if (g_seekable_seek (G_SEEKABLE (data->handle), offset, type, NULL, &err)) {
        return g_seekable_tell (G_SEEKABLE (data->handle));
    }

    xmms_error_set (error, XMMS_ERROR_GENERIC, err->message);
    return -1;
}
Exemple #4
0
static gboolean
try_seek_on_read (GVfsBackend *backend,
                  GVfsJobSeekRead *job,
                  GVfsBackendHandle handle,
                  goffset    offset,
                  GSeekType  type)
{
  GInputStream    *stream;
  GError          *error = NULL;

  stream = G_INPUT_STREAM (handle);

  if (!g_seekable_seek (G_SEEKABLE (stream), offset, type,
                        G_VFS_JOB (job)->cancellable, &error))
    {
      g_vfs_job_failed_literal (G_VFS_JOB (job),
                                error->domain,
                                error->code,
                                error->message);
      g_error_free (error);
      return FALSE;
    }
  else
    {
      g_vfs_job_seek_read_set_offset (job, g_seekable_tell (G_SEEKABLE (stream)));
      g_vfs_job_succeeded (G_VFS_JOB (job));
    }

  return TRUE;
}
static gboolean
gst_gio_base_src_start (GstBaseSrc * base_src)
{
  GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src);
  GstGioBaseSrcClass *gbsrc_class = GST_GIO_BASE_SRC_GET_CLASS (src);

  src->position = 0;

  /* FIXME: This will likely block */
  src->stream = gbsrc_class->get_stream (src);
  if (G_UNLIKELY (!G_IS_INPUT_STREAM (src->stream))) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("No input stream provided by subclass"));
    return FALSE;
  } else if (G_UNLIKELY (g_input_stream_is_closed (src->stream))) {
    GST_ELEMENT_ERROR (src, LIBRARY, FAILED, (NULL),
        ("Input stream is already closed"));
    return FALSE;
  }

  if (G_IS_SEEKABLE (src->stream))
    src->position = g_seekable_tell (G_SEEKABLE (src->stream));

  GST_DEBUG_OBJECT (src, "started source");

  return TRUE;
}
static void
extract_gibest_hash (GTask        *task,
                     gpointer      source_object,
                     gpointer      task_data,
                     GCancellable *cancellable)
{
  GFile *file = source_object;
  guint64 buffer[2][CHUNK_N_BYTES/8];
  GInputStream *stream = NULL;
  gssize n_bytes, file_size;
  GError *error = NULL;
  guint64 hash = 0;
  gint i;
  char *str;
  ResolveData *resolve_data = task_data;
  GrlLocalMetadataSourcePriv *priv;

  priv = GRL_LOCAL_METADATA_SOURCE_GET_PRIVATE (resolve_data->source);

  stream = G_INPUT_STREAM (g_file_read (file, cancellable, &error));
  if (stream == NULL)
    goto fail;

  /* Extract start/end chunks of the file */
  n_bytes = g_input_stream_read (stream, buffer[0], CHUNK_N_BYTES, cancellable, &error);
  if (n_bytes == -1)
    goto fail;

  if (!g_seekable_seek (G_SEEKABLE (stream), -CHUNK_N_BYTES, G_SEEK_END, cancellable, &error))
    goto fail;

  n_bytes = g_input_stream_read (stream, buffer[1], CHUNK_N_BYTES, cancellable, &error);
  if (n_bytes == -1)
    goto fail;

  for (i = 0; i < G_N_ELEMENTS (buffer[0]); i++)
    hash += buffer[0][i] + buffer[1][i];

  file_size = g_seekable_tell (G_SEEKABLE (stream));

  if (file_size < CHUNK_N_BYTES)
    goto fail;

  /* Include file size */
  hash += file_size;
  g_object_unref (stream);

  str = g_strdup_printf ("%" G_GINT64_FORMAT, hash);
  grl_data_set_string (GRL_DATA (resolve_data->rs->media), priv->hash_keyid, str);
  g_free (str);

  g_task_return_boolean (task, TRUE);
  return;

fail:
  GRL_DEBUG ("Could not get file hash: %s\n", error ? error->message : "Unknown error");
  g_task_return_error (task, error);
  g_clear_object (&stream);
}
Exemple #7
0
static int64_t
ddb_gvfs_tell (DB_FILE *stream)
{
  vfs_gvfs_data_t *data = (vfs_gvfs_data_t *) stream;

  g_return_val_if_fail (data != NULL, -1);
  g_return_val_if_fail (! g_input_stream_is_closed (data->handle), -1);

  return g_seekable_tell (G_SEEKABLE (data->handle));
}
Exemple #8
0
static goffset
g_resource_file_input_stream_tell (GFileInputStream *stream)
{
  GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream);;

  if (!G_IS_SEEKABLE (file->stream));
      return 0;

  return g_seekable_tell (G_SEEKABLE (file->stream));
}
Exemple #9
0
    arrow::Status Tell(int64_t *position) const override {
      if (!G_IS_SEEKABLE(output_stream_)) {
        std::string message("[gio-output-stream][tell] "
                            "not seekable output stream: <");
        message += G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(output_stream_));
        message += ">";
        return arrow::Status::NotImplemented(message);
      }

      *position = g_seekable_tell(G_SEEKABLE(output_stream_));
      return arrow::Status::OK();
    }
Exemple #10
0
static toff_t
seek_in_stream(thandle_t handle,
               toff_t offset,
               int whence)
{
  Priv *p = (Priv*) handle;
  GError *error = NULL;
  gboolean sought = FALSE;
  goffset position = -1;

  g_assert(p->stream);

  if (p->can_seek)
    {
      sought = g_seekable_seek(G_SEEKABLE(p->stream),
                               (goffset) offset, lseek_to_seek_type(whence),
                               NULL, &error);
      if (sought)
        position = g_seekable_tell(G_SEEKABLE(p->stream));
      else
        {
          g_warning("%s", error->message);
          g_error_free(error);
        }
    }
  else
    {
      switch (whence)
        {
        default:
        case SEEK_SET:
          if (offset <= p->allocated)
            position = p->position = offset;
          break;

        case SEEK_CUR:
          if (p->position + offset <= p->allocated)
            position = p->position += offset;
          break;

        case G_SEEK_END:
          position = p->position = p->allocated + offset;
          break;
        }
    }

  return (toff_t) position;
}
Exemple #11
0
static gboolean
read_head_data(GInputStream *stream, guchar *buffer, gsize buffer_size,
               gsize *read_bytes)
{
    GSeekable *seekable;
    gsize original_position;
    GError *error = NULL;

    if (!G_IS_SEEKABLE(stream))
        return FALSE;

    seekable = G_SEEKABLE(stream);
    original_position = g_seekable_tell(seekable);
    g_seekable_seek(seekable, 0, G_SEEK_SET, NULL, &error);
    if (error) {
        chupa_error("failed to seek to the head to guess content-type: %s",
                    error->message);
        g_error_free(error);
        return FALSE;
    }

    *read_bytes = g_input_stream_read(stream, buffer, buffer_size, NULL, &error);
    if (error) {
        chupa_error("failed to read head data to guess content-type: %s",
                    error->message);
        g_error_free(error);
        g_seekable_seek(seekable, original_position, G_SEEK_SET, NULL, NULL);
        return FALSE;
    }

    g_seekable_seek(seekable, original_position, G_SEEK_SET, NULL, &error);
    if (error) {
        chupa_error("failed to re-seek to the original position "
                    "to reset position to guess content-type: %s",
                    error->message);
        g_error_free(error);
        return FALSE;
    }

    return TRUE;
}
Exemple #12
0
static gboolean
trash_backend_seek_on_read (GVfsBackend       *backend,
                            GVfsJobSeekRead   *job,
                            GVfsBackendHandle  handle,
                            goffset            offset,
                            GSeekType          type) 
{
  GError *error = NULL;

  if (g_seekable_seek (handle, offset, type, NULL, &error))
    {
      g_vfs_job_seek_read_set_offset (job, g_seekable_tell (handle));
      g_vfs_job_succeeded (G_VFS_JOB (job));

      return TRUE;
    }

  g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
  g_error_free (error);

  return TRUE;
}
static toff_t
tiff_seek (thandle_t handle, toff_t offset, int whence)
{
	Handle    *h = HANDLE (handle);
	GSeekType  seek_type;

	seek_type = G_SEEK_SET;
        switch (whence) {
        case SEEK_SET:
        	seek_type = G_SEEK_SET;
                break;
        case SEEK_CUR:
        	seek_type = G_SEEK_CUR;
                break;
        case SEEK_END:
        	seek_type = G_SEEK_END;
                break;
        }

	if (! g_seekable_seek (G_SEEKABLE (h->istream), offset, seek_type, h->cancellable, NULL))
		return -1;

	return g_seekable_tell (G_SEEKABLE (h->istream));
}
Exemple #14
0
long long seekFile(PlatformFileHandle handle, long long offset, FileSeekOrigin origin)
{
    GSeekType seekType = G_SEEK_SET;
    switch (origin) {
    case SeekFromBeginning:
        seekType = G_SEEK_SET;
        break;
    case SeekFromCurrent:
        seekType = G_SEEK_CUR;
        break;
    case SeekFromEnd:
        seekType = G_SEEK_END;
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    if (!g_seekable_seek(G_SEEKABLE(g_io_stream_get_input_stream(G_IO_STREAM(handle))),
        offset, seekType, 0, 0))
    {
        return -1;
    }
    return g_seekable_tell(G_SEEKABLE(g_io_stream_get_input_stream(G_IO_STREAM(handle))));
}
static GstFlowReturn
gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
    GstBuffer ** buffer)
{
  GstSplitFileSrc *src = GST_SPLIT_FILE_SRC (basesrc);
  GstFilePart cur_part;
  GInputStream *stream;
  GCancellable *cancel;
  GSeekable *seekable;
  GstBuffer *buf;
  GError *err = NULL;
  guint64 read_offset;
  guint8 *data;
  guint to_read;

  cur_part = src->parts[src->cur_part];
  if (offset < cur_part.start || offset > cur_part.stop) {
    if (!gst_split_file_src_find_part_for_offset (src, offset, &src->cur_part))
      return GST_FLOW_UNEXPECTED;
    cur_part = src->parts[src->cur_part];
  }

  GST_LOG_OBJECT (src, "current part: %u (%" G_GUINT64_FORMAT " - "
      "%" G_GUINT64_FORMAT ", %s)", src->cur_part, cur_part.start,
      cur_part.stop, cur_part.path);

  buf = gst_buffer_new_and_alloc (size);

  GST_BUFFER_OFFSET (buf) = offset;

  data = GST_BUFFER_DATA (buf);

  cancel = src->cancellable;

  while (size > 0) {
    guint64 bytes_to_end_of_part;
    gsize read = 0;

    /* we want the offset into the file part */
    read_offset = offset - cur_part.start;

    GST_LOG ("Reading part %03u from offset %" G_GUINT64_FORMAT " (%s)",
        src->cur_part, read_offset, cur_part.path);

    /* FIXME: only seek when needed (hopefully gio is smart) */
    seekable = G_SEEKABLE (cur_part.stream);
    if (!g_seekable_seek (seekable, read_offset, G_SEEK_SET, cancel, &err))
      goto seek_failed;

    GST_LOG_OBJECT (src, "now: %" G_GUINT64_FORMAT, g_seekable_tell (seekable));

    bytes_to_end_of_part = (cur_part.stop - cur_part.start) + 1 - read_offset;
    to_read = MIN (size, bytes_to_end_of_part);

    GST_LOG_OBJECT (src, "reading %u bytes from part %u (bytes to end of "
        "part: %u)", to_read, src->cur_part, (guint) bytes_to_end_of_part);

    stream = G_INPUT_STREAM (cur_part.stream);

    /* NB: we won't try to read beyond EOF */
    if (!g_input_stream_read_all (stream, data, to_read, &read, cancel, &err))
      goto read_failed;

    GST_LOG_OBJECT (src, "read %u bytes", (guint) read);

    data += read;
    size -= read;
    offset += read;

    /* are we done? */
    if (size == 0)
      break;

    GST_LOG_OBJECT (src, "%u bytes left to read for this chunk", size);

    /* corner case, this should never really happen (assuming basesrc clips
     * requests beyond the file size) */
    if (read < to_read) {
      if (src->cur_part == src->num_parts - 1) {
        /* last file part, stop reading and truncate buffer */
        GST_BUFFER_SIZE (buf) = offset - GST_BUFFER_OFFSET (buf);
        break;
      } else {
        goto file_part_changed;
      }
    }

    ++src->cur_part;
    cur_part = src->parts[src->cur_part];
  }

  GST_BUFFER_OFFSET_END (buf) = offset;

  *buffer = buf;
  GST_LOG_OBJECT (src, "read %u bytes into buf %p", GST_BUFFER_SIZE (buf), buf);
  return GST_FLOW_OK;

/* ERRORS */
seek_failed:
  {
    if (err->code == G_IO_ERROR_CANCELLED)
      goto cancelled;

    GST_ELEMENT_ERROR (src, RESOURCE, SEEK, (NULL),
        ("Seek to %" G_GUINT64_FORMAT " in %s failed", read_offset,
            cur_part.path));
    g_error_free (err);
    gst_buffer_unref (buf);
    return GST_FLOW_ERROR;
  }
read_failed:
  {
    if (err->code == G_IO_ERROR_CANCELLED)
      goto cancelled;

    GST_ELEMENT_ERROR (src, RESOURCE, READ, ("%s", err->message),
        ("Read from %" G_GUINT64_FORMAT " in %s failed", read_offset,
            cur_part.path));
    g_error_free (err);
    gst_buffer_unref (buf);
    return GST_FLOW_ERROR;
  }
file_part_changed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, READ,
        ("Read error while reading file part %s", cur_part.path),
        ("Short read in file part, file may have been modified since start"));
    gst_buffer_unref (buf);
    return GST_FLOW_ERROR;
  }
cancelled:
  {
    GST_DEBUG_OBJECT (src, "I/O operation cancelled from another thread");
    g_error_free (err);
    gst_buffer_unref (buf);
    return GST_FLOW_WRONG_STATE;
  }
}
Exemple #16
0
static int64_t gio_ftell (VFSFile * file)
{
    FileData * data = vfs_get_handle (file);
    return g_seekable_tell (data->seekable);
}
Exemple #17
0
gboolean check_bundle(const gchar *bundlename, gsize *size, gboolean verify, GError **error) {
	GError *ierror = NULL;
	GBytes *sig = NULL;
	GFile *bundlefile = NULL;
	GFileInputStream *bundlestream = NULL;
	guint64 sigsize;
	goffset offset;
	gboolean res = FALSE;

	r_context_begin_step("check_bundle", "Checking bundle", verify);

	if (!r_context()->config->keyring_path) {
		g_set_error(error, G_FILE_ERROR, G_FILE_ERROR_EXIST, "No keyring file provided");
		goto out;
	}

	g_message("Reading bundle: %s", bundlename);

	bundlefile = g_file_new_for_path(bundlename);
	bundlestream = g_file_read(bundlefile, NULL, &ierror);
	if (bundlestream == NULL) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to open bundle for reading: ");
		goto out;
	}

	offset = sizeof(sigsize);
	res = g_seekable_seek(G_SEEKABLE(bundlestream),
			      -offset, G_SEEK_END, NULL, &ierror);
	if (!res) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to seek to end of bundle: ");
		goto out;
	}
	offset = g_seekable_tell((GSeekable *)bundlestream);

	res = input_stream_read_uint64_all(G_INPUT_STREAM(bundlestream),
			                   &sigsize, NULL, &ierror);
	if (!res) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to read signature size from bundle: ");
		goto out;
	}

	offset -= sigsize;

	if (size)
		*size = offset;

	res = g_seekable_seek(G_SEEKABLE(bundlestream),
			      offset, G_SEEK_SET, NULL, &ierror);
	if (!res) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to seek to start of bundle signature: ");
		goto out;
	}

	res = input_stream_read_bytes_all(G_INPUT_STREAM(bundlestream),
			                  &sig, sigsize, NULL, &ierror);
	if (!res) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to read signature from bundle: ");
		goto out;
	}

	if (verify) {
		g_message("Verifying bundle... ");
		/* the squashfs image size is in offset */
		res = cms_verify_file(bundlename, sig, offset, &ierror);
		if (!res) {
			g_propagate_error(error, ierror);
			goto out;
		}
	}

	res = TRUE;
out:
	g_clear_object(&bundlestream);
	g_clear_object(&bundlefile);
	g_clear_pointer(&sig, g_bytes_unref);
	r_context_end_step("check_bundle", res);
	return res;
}
Exemple #18
0
gboolean create_bundle(const gchar *bundlename, const gchar *contentdir, GError **error) {
	GError *ierror = NULL;
	GBytes *sig = NULL;
	GFile *bundlefile = NULL;
	GFileOutputStream *bundlestream = NULL;
	gboolean res = FALSE;
	guint64 offset;

	g_assert_nonnull(r_context()->certpath);
	g_assert_nonnull(r_context()->keypath);

	res = mksquashfs(bundlename, contentdir, &ierror);
	if (!res) {
		g_propagate_error(error, ierror);
		goto out;
	}

	sig = cms_sign_file(bundlename,
			    r_context()->certpath,
			    r_context()->keypath,
			    &ierror);
	if (sig == NULL) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed signing bundle: ");
		goto out;
	}

	bundlefile = g_file_new_for_path(bundlename);
	bundlestream = g_file_append_to(bundlefile, G_FILE_CREATE_NONE, NULL, &ierror);
	if (bundlestream == NULL) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to open bundle for appending: ");
		goto out;
	}

	res = g_seekable_seek(G_SEEKABLE(bundlestream),
			      0, G_SEEK_END, NULL, &ierror);
	if (!res) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to seek to end of bundle: ");
		goto out;
	}

	offset = g_seekable_tell((GSeekable *)bundlestream);
	res = output_stream_write_bytes_all((GOutputStream *)bundlestream, sig, NULL, &ierror);
	if (!res) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to append signature to bundle: ");
		goto out;
	}


	offset = g_seekable_tell((GSeekable *)bundlestream) - offset;
	res = output_stream_write_uint64_all((GOutputStream *)bundlestream, offset, NULL, &ierror);
	if (!res) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to append signature size to bundle: ");
		goto out;
	}


	res = TRUE;
out:
	g_clear_object(&bundlestream);
	g_clear_object(&bundlefile);
	g_clear_pointer(&sig, g_bytes_unref);
	return res;
}
static gboolean
gst_gio_base_src_get_size (GstBaseSrc * base_src, guint64 * size)
{
  GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src);

  if (G_IS_FILE_INPUT_STREAM (src->stream)) {
    GFileInfo *info;
    GError *err = NULL;

    info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (src->stream),
        G_FILE_ATTRIBUTE_STANDARD_SIZE, src->cancel, &err);

    if (info != NULL) {
      *size = g_file_info_get_size (info);
      g_object_unref (info);
      GST_DEBUG_OBJECT (src, "found size: %" G_GUINT64_FORMAT, *size);
      return TRUE;
    }

    if (!gst_gio_error (src, "g_file_input_stream_query_info", &err, NULL)) {

      if (GST_GIO_ERROR_MATCHES (err, NOT_SUPPORTED))
        GST_DEBUG_OBJECT (src, "size information not available");
      else
        GST_WARNING_OBJECT (src, "size information retrieval failed: %s",
            err->message);

      g_clear_error (&err);
    }
  }

  if (GST_GIO_STREAM_IS_SEEKABLE (src->stream)) {
    goffset old;
    goffset stream_size;
    gboolean ret;
    GSeekable *seekable = G_SEEKABLE (src->stream);
    GError *err = NULL;

    old = g_seekable_tell (seekable);

    ret = g_seekable_seek (seekable, 0, G_SEEK_END, src->cancel, &err);
    if (!ret) {
      if (!gst_gio_error (src, "g_seekable_seek", &err, NULL)) {
        if (GST_GIO_ERROR_MATCHES (err, NOT_SUPPORTED))
          GST_DEBUG_OBJECT (src,
              "Seeking to the end of stream is not supported");
        else
          GST_WARNING_OBJECT (src, "Seeking to end of stream failed: %s",
              err->message);
        g_clear_error (&err);
      } else {
        GST_WARNING_OBJECT (src, "Seeking to end of stream failed");
      }
      return FALSE;
    }

    stream_size = g_seekable_tell (seekable);

    ret = g_seekable_seek (seekable, old, G_SEEK_SET, src->cancel, &err);
    if (!ret) {
      if (!gst_gio_error (src, "g_seekable_seek", &err, NULL)) {
        if (GST_GIO_ERROR_MATCHES (err, NOT_SUPPORTED))
          GST_ERROR_OBJECT (src, "Seeking to the old position not supported");
        else
          GST_ERROR_OBJECT (src, "Seeking to the old position failed: %s",
              err->message);
        g_clear_error (&err);
      } else {
        GST_ERROR_OBJECT (src, "Seeking to the old position faile");
      }
      return FALSE;
    }

    if (stream_size >= 0) {
      *size = stream_size;
      return TRUE;
    }
  }

  return FALSE;
}
Exemple #20
0
    bool verify_and_strip_signatures()
    {
        g_debug( "CHECKING SIGNATURE(S)" );

        Signature::Info::List signatures;

        gsize signature_length = 0;

        // This means that the signatures are invalid or we had a problem
        // dealing with them. If there are no signatures, this will return
        // true and give us an empty list.

        if ( ! Signature::get_signatures( info.source_file.c_str(), signatures, &signature_length ) )
        {
            return false;
        }

        unsigned int found = 0;

        if ( signatures.empty() )
        {
            g_debug( "  NOT SIGNED" );
        }
        else
        {
            for ( Signature::Info::List::const_iterator it = signatures.begin(); it != signatures.end(); ++it )
            {
                info.fingerprints.insert( it->fingerprint );
            }

            // Now, see how many of the required ones are found in the signatures

            for ( StringSet::const_iterator it = info.required_fingerprints.begin(); it != info.required_fingerprints.end(); ++it )
            {
                found += info.fingerprints.count( *it );
            }
        }

        if ( found != info.required_fingerprints.size() )
        {
            // Signature(s) missing

            g_warning( "APP IS MISSING AT LEAST ONE REQUIRED SIGNATURE" );

            return false;
        }

        // If there were no signatures, we are done

        if ( signatures.empty() )
        {
            return true;
        }

        // Otherwise, we need to strip the signature block from the file

        bool result = false;

        GFile * file = g_file_new_for_path( info.source_file.c_str() );

        if ( file )
        {

            GFileIOStream * stream = g_file_open_readwrite( file, NULL, NULL );

            if ( stream )
            {
                GSeekable * seekable = G_SEEKABLE( stream );

                if ( g_seekable_can_seek( seekable ) && g_seekable_can_truncate( seekable ) )
                {
                    if ( g_seekable_seek( seekable, 0, G_SEEK_END, NULL, NULL ) )
                    {
                        goffset file_size = g_seekable_tell( seekable );

                        file_size -= signature_length;

                        if ( g_seekable_truncate( seekable, file_size, NULL, NULL ) )
                        {
                            g_debug( "TRUNCATING FILE TO %" G_GOFFSET_FORMAT " BYTES", file_size );
                            result = true;
                        }
                    }
                }

                g_io_stream_close( G_IO_STREAM( stream ), NULL, NULL );

                g_object_unref( G_OBJECT( stream ) );
            }

            g_object_unref( G_OBJECT( file ) );
        }

        if ( ! result )
        {
            g_warning( "FAILED TO STRIP SIGNATURE(S)" );
        }

        return result;
    }
Exemple #21
0
static VALUE
rg_tell(VALUE self)
{
        return GOFFSET2RVAL(g_seekable_tell(_SELF(self)));
}