/** * 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; }
/* * 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)); }
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; }
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); }
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)); }
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)); }
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(); }
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; }
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; }
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)); }
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; } }
static int64_t gio_ftell (VFSFile * file) { FileData * data = vfs_get_handle (file); return g_seekable_tell (data->seekable); }
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; }
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; }
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; }
static VALUE rg_tell(VALUE self) { return GOFFSET2RVAL(g_seekable_tell(_SELF(self))); }