void lllp_connected_cb(GObject *listener, GAsyncResult *res, gpointer pstore_library) { GtkListStore *store_library = GTK_LIST_STORE(pstore_library); GSocketConnection *connection; GSocketAddress *address; gchar *address_char; GInputStream *stream; GFile *output_file; GOutputStream *file_stream; gsize count; gboolean valid = FALSE; connection = g_socket_listener_accept_finish(G_SOCKET_LISTENER(listener), res, NULL, NULL); address = g_socket_connection_get_remote_address(connection, NULL); address_char = g_inet_address_to_string(g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(address))); printf("%s\n", address_char); output_file = g_file_new_for_path(address_char); g_file_delete(output_file, NULL, NULL); file_stream = (GOutputStream*)g_file_replace(output_file, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, NULL); stream = g_io_stream_get_input_stream(G_IO_STREAM(connection)); g_output_stream_splice(file_stream, stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, NULL, NULL); g_output_stream_close(file_stream, NULL, NULL); convert_library_to_list_store(store_library, address_char); printf("%s CONNECTED\n", address_char); g_socket_listener_accept_async(G_SOCKET_LISTENER(listener), NULL, lllp_connected_cb, store_library); }
static GBytes * download_uri (SoupURI *uri, GError **error) { g_autoptr(SoupSession) session = NULL; g_autoptr(SoupRequest) req = NULL; g_autoptr(GInputStream) input = NULL; g_autoptr(GOutputStream) out = NULL; g_assert (uri != NULL); session = get_soup_session (); req = soup_session_request_uri (session, uri, error); if (req == NULL) return NULL; input = soup_request_send (req, NULL, error); if (input == NULL) return NULL; out = g_memory_output_stream_new_resizable (); if (!g_output_stream_splice (out, input, G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, NULL, error)) return NULL; return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out)); }
static gboolean decompress_all (GConverter *converter, GBytes *data, GBytes **out_uncompressed, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autoptr(GMemoryInputStream) memin = (GMemoryInputStream*)g_memory_input_stream_new_from_bytes (data); g_autoptr(GMemoryOutputStream) memout = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free); g_autoptr(GInputStream) convin = g_converter_input_stream_new ((GInputStream*)memin, converter); { gssize n_bytes_written = g_output_stream_splice ((GOutputStream*)memout, convin, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error); if (n_bytes_written < 0) goto out; } ret = TRUE; *out_uncompressed = g_memory_output_stream_steal_as_bytes (memout); out: return ret; }
static GBytes * download_uri (const char *url, BuilderContext *context, GError **error) { SoupSession *session; g_autoptr(SoupRequest) req = NULL; g_autoptr(GInputStream) input = NULL; g_autoptr(GOutputStream) out = NULL; session = builder_context_get_soup_session (context); req = soup_session_request (session, url, error); if (req == NULL) return NULL; input = soup_request_send (req, NULL, error); if (input == NULL) return NULL; out = g_memory_output_stream_new_resizable (); if (!g_output_stream_splice (out, input, G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, NULL, error)) return NULL; return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out)); }
/** * Read all input from @src, allocating a new #GVariant from it into * output variable @out_variant. @src will be closed as a result. * * Note the returned @out_variant is not floating. */ gboolean ot_util_variant_from_stream (GInputStream *src, const GVariantType *type, gboolean trusted, GVariant **out_variant, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; gs_unref_object GMemoryOutputStream *data_stream = NULL; gs_unref_variant GVariant *ret_variant = NULL; data_stream = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free); if (g_output_stream_splice ((GOutputStream*)data_stream, src, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error) < 0) goto out; ret_variant = g_variant_new_from_data (type, g_memory_output_stream_get_data (data_stream), g_memory_output_stream_get_data_size (data_stream), trusted, (GDestroyNotify) g_object_unref, data_stream); data_stream = NULL; /* Transfer ownership */ g_variant_ref_sink (ret_variant); ret = TRUE; ot_transfer_out_value (out_variant, &ret_variant); out: return ret; }
gboolean ot_gio_splice_update_checksum (GOutputStream *out, GInputStream *in, GChecksum *checksum, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_return_val_if_fail (out != NULL || checksum != NULL, FALSE); if (checksum != NULL) { gsize bytes_read, bytes_written; char buf[4096]; do { if (!g_input_stream_read_all (in, buf, sizeof(buf), &bytes_read, cancellable, error)) goto out; if (!ot_gio_write_update_checksum (out, buf, bytes_read, &bytes_written, checksum, cancellable, error)) goto out; } while (bytes_read > 0); } else { if (g_output_stream_splice (out, in, 0, cancellable, error) < 0) goto out; } ret = TRUE; out: return ret; }
static gboolean handle_userdata_script (MinCloudAgentApp *self, GInputStream *instream, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; gs_free char *tmppath = g_strdup ("/var/tmp/userdata-script.XXXXXX"); gs_unref_object GOutputStream *outstream = NULL; int fd; fd = g_mkstemp_full (tmppath, O_WRONLY, 0700); if (fd == -1) { int errsv = errno; g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to create temporary userdata script: %s", g_strerror (errsv)); goto out; } outstream = g_unix_output_stream_new (fd, TRUE); if (0 > g_output_stream_splice ((GOutputStream*)outstream, instream, G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, self->cancellable, error)) goto out; gs_log_structured_print_id_v (MCA_USERDATA_EXECUTING_ID, "Executing user data script"); if (!gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_NULL, cancellable, error, tmppath, NULL)) { gs_log_structured_print_id_v (MCA_USERDATA_FAILED_ID, "User data script failed"); goto out; } gs_log_structured_print_id_v (MCA_USERDATA_SUCCESS_ID, "User data script suceeded"); if (!g_file_replace_contents (self->userdata_done_stamp, "done\n", 5, NULL, FALSE, 0, NULL, cancellable, error)) goto out; ret = TRUE; out: (void) unlink (tmppath); return ret; }
static gboolean fetch_uri_contents_utf8_sync (OtPullData *pull_data, SoupURI *uri, char **out_contents, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const guint8 nulchar = 0; gs_free char *ret_contents = NULL; gs_unref_object GMemoryOutputStream *buf = NULL; OstreeFetchUriSyncData fetch_data = { 0, }; if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; fetch_data.pull_data = pull_data; pull_data->fetching_sync_uri = uri; ostree_fetcher_stream_uri_async (pull_data->fetcher, uri, cancellable, fetch_uri_sync_on_complete, &fetch_data); run_mainloop_monitor_fetcher (pull_data); if (!fetch_data.result_stream) goto out; buf = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free); if (g_output_stream_splice ((GOutputStream*)buf, fetch_data.result_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, cancellable, error) < 0) goto out; /* Add trailing NUL */ if (!g_output_stream_write ((GOutputStream*)buf, &nulchar, 1, cancellable, error)) goto out; if (!g_output_stream_close ((GOutputStream*)buf, cancellable, error)) goto out; ret_contents = g_memory_output_stream_steal_data (buf); if (!g_utf8_validate (ret_contents, -1, NULL)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid UTF-8"); goto out; } ret = TRUE; ot_transfer_out_value (out_contents, &ret_contents); out: g_clear_object (&(fetch_data.result_stream)); return ret; }
static GBytes * read_gpg_data (GCancellable *cancellable, GError **error) { g_autoptr(GInputStream) source_stream = NULL; g_autoptr(GOutputStream) mem_stream = NULL; guint n_keyrings = 0; g_autoptr(GPtrArray) streams = NULL; if (opt_gpg_file != NULL) n_keyrings = g_strv_length (opt_gpg_file); guint ii; streams = g_ptr_array_new_with_free_func (g_object_unref); for (ii = 0; ii < n_keyrings; ii++) { GInputStream *input_stream = NULL; if (strcmp (opt_gpg_file[ii], "-") == 0) { input_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE); } else { g_autoptr(GFile) file = g_file_new_for_path (opt_gpg_file[ii]); input_stream = G_INPUT_STREAM(g_file_read (file, cancellable, error)); if (input_stream == NULL) return NULL; } /* Takes ownership. */ g_ptr_array_add (streams, input_stream); } /* Chain together all the --keyring options as one long stream. */ source_stream = (GInputStream *) xdg_app_chain_input_stream_new (streams); mem_stream = g_memory_output_stream_new_resizable (); if (g_output_stream_splice (mem_stream, source_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error) < 0) return NULL; return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mem_stream)); }
static VALUE rg_splice(int argc, VALUE *argv, VALUE self) { VALUE source, flags, cancellable; GError *error = NULL; gssize bytes_spliced; rb_scan_args(argc, argv, "12", &source, &flags, &cancellable); bytes_spliced = g_output_stream_splice(_SELF(self), RVAL2GINPUTSTREAM(source), RVAL2GOUTPUTSTREAMSPLICEFLAGSDEFAULT(flags), RVAL2GCANCELLABLE(cancellable), &error); if (bytes_spliced == -1) rbgio_raise_error(error); return GSSIZE2RVAL(bytes_spliced); }
static gboolean cat_one_file (GFile *f, GOutputStream *stdout_stream, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; gs_unref_object GInputStream *in = NULL; in = (GInputStream*)g_file_read (f, cancellable, error); if (!in) goto out; if (!g_output_stream_splice (stdout_stream, in, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, cancellable, error)) goto out; ret = TRUE; out: return ret; }
bool gunzip_file(const char *path) { GFile *in = NULL, *out = NULL; autofree(gchar) *newpath = NULL; autofree(GFileInputStream) *fis = NULL; autofree(GFileOutputStream) *fos = NULL; autofree(GOutputStream) *cos = NULL; autofree(GZlibDecompressor) *conv = NULL; gsize ret; newpath = g_strdup(path); if (g_str_has_suffix(newpath, ".gz")) { newpath = str_replace(newpath, ".gz", ""); } in = g_file_new_for_path(path); out = g_file_new_for_path(newpath); fis = g_file_read(in, NULL, NULL); if (!fis) { return NULL; } fos = g_file_replace(out, NULL, FALSE, 0, NULL, NULL); if (!fos) { return NULL; } conv = g_zlib_decompressor_new(G_ZLIB_COMPRESSOR_FORMAT_GZIP); cos = g_converter_output_stream_new(G_OUTPUT_STREAM(fos), G_CONVERTER(conv)); if (!cos) { return NULL; } ret = g_output_stream_splice(cos, G_INPUT_STREAM(fis), G_OUTPUT_STREAM_SPLICE_NONE, NULL, NULL); return (ret > 0 ? true : false ); }
gboolean _ostree_static_delta_part_open (GInputStream *part_in, GBytes *inline_part_bytes, OstreeStaticDeltaOpenFlags flags, const char *expected_checksum, GVariant **out_part, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const gboolean trusted = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED) > 0; const gboolean skip_checksum = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM) > 0; gsize bytes_read; guint8 comptype; g_autoptr(GChecksum) checksum = NULL; g_autoptr(GInputStream) checksum_in = NULL; g_autoptr(GVariant) ret_part = NULL; GInputStream *source_in; /* We either take a fd or a GBytes reference */ g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (part_in) || inline_part_bytes != NULL, FALSE); g_return_val_if_fail (skip_checksum || expected_checksum != NULL, FALSE); if (!skip_checksum) { checksum = g_checksum_new (G_CHECKSUM_SHA256); checksum_in = (GInputStream*)ostree_checksum_input_stream_new (part_in, checksum); source_in = checksum_in; } else { source_in = part_in; } { guint8 buf[1]; /* First byte is compression type */ if (!g_input_stream_read_all (source_in, buf, sizeof(buf), &bytes_read, cancellable, error)) { g_prefix_error (error, "Reading initial compression flag byte: "); goto out; } comptype = buf[0]; } switch (comptype) { case 0: if (!inline_part_bytes) { int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)part_in); /* No compression, no checksums - a fast path */ if (!ot_util_variant_map_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) goto out; } else { g_autoptr(GBytes) content_bytes = g_bytes_new_from_bytes (inline_part_bytes, 1, g_bytes_get_size (inline_part_bytes) - 1); ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), content_bytes, trusted); g_variant_ref_sink (ret_part); } if (!skip_checksum) g_checksum_update (checksum, g_variant_get_data (ret_part), g_variant_get_size (ret_part)); break; case 'x': { g_autofree char *tmppath = g_strdup ("/var/tmp/ostree-delta-XXXXXX"); g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new (); g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp); g_autoptr(GOutputStream) unpacked_out = NULL; glnx_fd_close int unpacked_fd = -1; gssize n_bytes_written; unpacked_fd = g_mkstemp_full (tmppath, O_RDWR | O_CLOEXEC, 0640); if (unpacked_fd < 0) { glnx_set_error_from_errno (error); goto out; } /* Now make it autocleanup on process exit - in the future, we * should consider caching unpacked deltas as well. */ if (unlink (tmppath) < 0) { glnx_set_error_from_errno (error); goto out; } unpacked_out = g_unix_output_stream_new (unpacked_fd, FALSE); n_bytes_written = g_output_stream_splice (unpacked_out, convin, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error); if (n_bytes_written < 0) goto out; if (!ot_util_variant_map_fd (unpacked_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) goto out; } break; default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid compression type '%u'", comptype); goto out; } if (checksum) { const char *actual_checksum = g_checksum_get_string (checksum); g_assert (expected_checksum != NULL); if (strcmp (actual_checksum, expected_checksum) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Checksum mismatch in static delta part; expected=%s actual=%s", expected_checksum, actual_checksum); goto out; } } ret = TRUE; *out_part = g_steal_pointer (&ret_part); out: return ret; }
static gboolean checkout_object_for_uncompressed_cache (OstreeRepo *self, const char *loose_path, GFileInfo *src_info, GInputStream *content, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autofree char *temp_filename = NULL; g_autoptr(GOutputStream) temp_out = NULL; int fd; int res; guint32 file_mode; /* Don't make setuid files in uncompressed cache */ file_mode = g_file_info_get_attribute_uint32 (src_info, "unix::mode"); file_mode &= ~(S_ISUID|S_ISGID); if (!gs_file_open_in_tmpdir_at (self->tmp_dir_fd, file_mode, &temp_filename, &temp_out, cancellable, error)) goto out; if (g_output_stream_splice (temp_out, content, 0, cancellable, error) < 0) goto out; if (!g_output_stream_flush (temp_out, cancellable, error)) goto out; fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)temp_out); if (!self->disable_fsync) { do res = fsync (fd); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } } if (!g_output_stream_close (temp_out, cancellable, error)) goto out; if (!_ostree_repo_ensure_loose_objdir_at (self->uncompressed_objects_dir_fd, loose_path, cancellable, error)) goto out; if (G_UNLIKELY (renameat (self->tmp_dir_fd, temp_filename, self->uncompressed_objects_dir_fd, loose_path) == -1)) { if (errno != EEXIST) { glnx_set_error_from_errno (error); g_prefix_error (error, "Storing file '%s': ", temp_filename); goto out; } else (void) unlinkat (self->tmp_dir_fd, temp_filename, 0); } ret = TRUE; out: return ret; }
static void decompress_db (GFile *db, const char *path) { GFile *db_decomp; GFile *db_decomp_tmp; GError *error = NULL; GZlibDecompressor *conv; GInputStream *instream; GInputStream *instream_conv; GOutputStream *outstream; char *tmp_db_path; instream = (GInputStream *) g_file_read (db, NULL, &error); if (!instream) { g_print ("Error opening file: %s", error->message); g_error_free (error); return; } conv = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); instream_conv = (GInputStream *) g_converter_input_stream_new (instream, G_CONVERTER (conv)); g_object_unref (instream); tmp_db_path = g_strdup_printf ("%s.%s", path, "tmp"); db_decomp_tmp = g_file_new_for_path (tmp_db_path); g_free (tmp_db_path); outstream = (GOutputStream *) g_file_replace (db_decomp_tmp, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error); if (!outstream) { g_print ("Error creating file: %s\n", error->message); g_error_free (error); goto end; } if (g_output_stream_splice (outstream, instream_conv, 0, NULL, &error) == -1) { g_print ("Error decompressing the database: %s\n", error->message); g_object_unref (outstream); g_error_free (error); goto end; } if (g_output_stream_close (outstream, NULL, &error) == FALSE) { g_print ("Error decompressing the database: %s\n", error->message); g_error_free (error); } else { db_decomp = g_file_new_for_path (path); if (g_file_move (db_decomp_tmp, db_decomp, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error) == FALSE) { g_print ("Error moving the temporary database file to the" \ " original database file: %s\n", error->message); g_error_free (error); } else { g_print ("Database updated\n"); } g_object_unref (db_decomp); } g_object_unref (outstream); end: g_object_unref (db_decomp_tmp); g_object_unref (conv); g_object_unref (instream_conv); }
gboolean rpmostree_compose_builtin_sign (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context = g_option_context_new ("- Use rpm-sign to sign an OSTree commit"); gs_unref_object GFile *repopath = NULL; gs_unref_object OstreeRepo *repo = NULL; gs_unref_object GFile *tmp_commitdata_file = NULL; gs_unref_object GFileIOStream *tmp_sig_stream = NULL; gs_unref_object GFile *tmp_sig_file = NULL; gs_unref_object GFileIOStream *tmp_commitdata_stream = NULL; GOutputStream *tmp_commitdata_output = NULL; gs_unref_object GInputStream *commit_data = NULL; gs_free char *checksum = NULL; gs_unref_variant GVariant *commit_variant = NULL; gs_unref_bytes GBytes *commit_bytes = NULL; if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, error)) goto out; if (!(opt_repo_path && opt_key_id && opt_rev)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Missing required argument"); goto out; } repopath = g_file_new_for_path (opt_repo_path); repo = ostree_repo_new (repopath); if (!ostree_repo_open (repo, cancellable, error)) goto out; if (!ostree_repo_resolve_rev (repo, opt_rev, FALSE, &checksum, error)) goto out; if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, &commit_variant, error)) goto out; commit_bytes = g_variant_get_data_as_bytes (commit_variant); commit_data = (GInputStream*)g_memory_input_stream_new_from_bytes (commit_bytes); tmp_commitdata_file = g_file_new_tmp ("tmpsigXXXXXX", &tmp_commitdata_stream, error); if (!tmp_commitdata_file) goto out; tmp_commitdata_output = (GOutputStream*)g_io_stream_get_output_stream ((GIOStream*)tmp_commitdata_stream); if (g_output_stream_splice ((GOutputStream*)tmp_commitdata_output, commit_data, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error) < 0) goto out; tmp_sig_file = g_file_new_tmp ("tmpsigoutXXXXXX", &tmp_sig_stream, error); if (!tmp_sig_file) goto out; (void) g_io_stream_close ((GIOStream*)tmp_sig_stream, NULL, NULL); if (!gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_NULL, cancellable, error, "rpm-sign", "--key", opt_key_id, "--detachsign", gs_file_get_path_cached (tmp_commitdata_file), "--output", gs_file_get_path_cached (tmp_sig_file), NULL)) goto out; { char *sigcontent = NULL; gsize len; gs_unref_bytes GBytes *sigbytes = NULL; if (!g_file_load_contents (tmp_sig_file, cancellable, &sigcontent, &len, NULL, error)) goto out; sigbytes = g_bytes_new_take (sigcontent, len); if (!ostree_repo_append_gpg_signature (repo, checksum, sigbytes, cancellable, error)) goto out; } g_print ("Successfully signed OSTree commit=%s with key=%s\n", checksum, opt_key_id); ret = TRUE; out: if (tmp_commitdata_file) (void) gs_file_unlink (tmp_commitdata_file, NULL, NULL); if (tmp_sig_file) (void) gs_file_unlink (tmp_sig_file, NULL, NULL); return ret; }
static gboolean write_regular_file_content (OstreeRepo *self, OstreeRepoCheckoutOptions *options, GOutputStream *output, GFileInfo *file_info, GVariant *xattrs, GInputStream *input, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const OstreeRepoCheckoutMode mode = options->mode; int fd; int res; if (g_output_stream_splice (output, input, 0, cancellable, error) < 0) goto out; if (!g_output_stream_flush (output, cancellable, error)) goto out; fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)output); if (mode != OSTREE_REPO_CHECKOUT_MODE_USER) { do res = fchown (fd, g_file_info_get_attribute_uint32 (file_info, "unix::uid"), g_file_info_get_attribute_uint32 (file_info, "unix::gid")); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } do res = fchmod (fd, g_file_info_get_attribute_uint32 (file_info, "unix::mode")); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } if (xattrs) { if (!glnx_fd_set_all_xattrs (fd, xattrs, cancellable, error)) goto out; } } if (fsync_is_enabled (self, options)) { if (fsync (fd) == -1) { glnx_set_error_from_errno (error); goto out; } } if (!g_output_stream_close (output, cancellable, error)) goto out; ret = TRUE; out: return ret; }
/** * ot_file_replace_contents_at: * * Like g_file_replace_contents(), except using a fd-relative * directory, and optionally enforces use of fdatasync(). */ gboolean ot_file_replace_contents_at (int dfd, const char *path, GBytes *contents, gboolean datasync, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; int fd; g_autofree char *tmpname = NULL; g_autoptr(GOutputStream) stream = NULL; g_autoptr(GInputStream) instream = NULL; if (!gs_file_open_in_tmpdir_at (dfd, 0644, &tmpname, &stream, cancellable, error)) goto out; g_assert (G_IS_FILE_DESCRIPTOR_BASED (stream)); fd = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (stream)); instream = g_memory_input_stream_new_from_bytes (contents); if (g_bytes_get_size (contents) > 0) { int r = posix_fallocate (fd, 0, g_bytes_get_size (contents)); if (r != 0) { /* posix_fallocate is a weird deviation from errno standards */ errno = r; glnx_set_error_from_errno (error); goto out; } } if (g_output_stream_splice (stream, instream, 0, cancellable, error) < 0) goto out; if (datasync && fdatasync (fd) != 0) { glnx_set_error_from_errno (error); goto out; } if (!g_output_stream_close (stream, cancellable, error)) goto out; if (renameat (dfd, tmpname, dfd, path) == -1) { glnx_set_error_from_errno (error); goto out; } g_clear_pointer (&tmpname, g_free); ret = TRUE; out: if (tmpname) (void) unlinkat (dfd, tmpname, 0); return ret; }
static gboolean checkout_object_for_uncompressed_cache (OstreeRepo *self, const char *loose_path, GFileInfo *src_info, GInputStream *content, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autofree char *temp_filename = NULL; g_autoptr(GOutputStream) temp_out = NULL; glnx_fd_close int fd = -1; int res; guint32 file_mode; /* Don't make setuid files in uncompressed cache */ file_mode = g_file_info_get_attribute_uint32 (src_info, "unix::mode"); file_mode &= ~(S_ISUID|S_ISGID); if (!glnx_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_WRONLY | O_CLOEXEC, &fd, &temp_filename, error)) goto out; temp_out = g_unix_output_stream_new (fd, FALSE); if (g_output_stream_splice (temp_out, content, 0, cancellable, error) < 0) goto out; if (!g_output_stream_flush (temp_out, cancellable, error)) goto out; if (!self->disable_fsync) { do res = fsync (fd); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } } if (!g_output_stream_close (temp_out, cancellable, error)) goto out; if (fchmod (fd, file_mode) < 0) { glnx_set_error_from_errno (error); goto out; } if (!_ostree_repo_ensure_loose_objdir_at (self->uncompressed_objects_dir_fd, loose_path, cancellable, error)) goto out; if (!glnx_link_tmpfile_at (self->tmp_dir_fd, GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST, fd, temp_filename, self->uncompressed_objects_dir_fd, loose_path, error)) goto out; ret = TRUE; out: return ret; }
gboolean ostree_create_file_from_input (GFile *dest_file, GFileInfo *finfo, GVariant *xattrs, GInputStream *input, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const char *dest_path; guint32 uid, gid, mode; ot_lobj GFileOutputStream *out = NULL; if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; if (finfo != NULL) { mode = g_file_info_get_attribute_uint32 (finfo, "unix::mode"); } else { mode = S_IFREG | 0664; } dest_path = ot_gfile_get_path_cached (dest_file); if (S_ISDIR (mode)) { if (mkdir (ot_gfile_get_path_cached (dest_file), mode) < 0) { ot_util_set_error_from_errno (error, errno); goto out; } } else if (S_ISREG (mode)) { out = g_file_create (dest_file, 0, cancellable, error); if (!out) goto out; if (input) { if (g_output_stream_splice ((GOutputStream*)out, input, 0, cancellable, error) < 0) goto out; } if (!g_output_stream_close ((GOutputStream*)out, NULL, error)) goto out; } else if (S_ISLNK (mode)) { const char *target = g_file_info_get_attribute_byte_string (finfo, "standard::symlink-target"); if (symlink (target, dest_path) < 0) { ot_util_set_error_from_errno (error, errno); goto out; } } else if (S_ISCHR (mode) || S_ISBLK (mode)) { guint32 dev = g_file_info_get_attribute_uint32 (finfo, "unix::rdev"); if (mknod (dest_path, mode, dev) < 0) { ot_util_set_error_from_errno (error, errno); goto out; } } else if (S_ISFIFO (mode)) { if (mkfifo (dest_path, mode) < 0) { ot_util_set_error_from_errno (error, errno); goto out; } } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid mode %u", mode); goto out; } if (finfo != NULL) { uid = g_file_info_get_attribute_uint32 (finfo, "unix::uid"); gid = g_file_info_get_attribute_uint32 (finfo, "unix::gid"); if (lchown (dest_path, uid, gid) < 0) { ot_util_set_error_from_errno (error, errno); g_prefix_error (error, "lchown(%u, %u) failed: ", uid, gid); goto out; } } if (!S_ISLNK (mode)) { if (chmod (dest_path, mode) < 0) { ot_util_set_error_from_errno (error, errno); g_prefix_error (error, "chmod(%u) failed: ", mode); goto out; } } if (xattrs != NULL) { if (!ostree_set_xattrs (dest_file, xattrs, cancellable, error)) goto out; } ret = TRUE; out: if (!ret && !S_ISDIR(mode)) { (void) unlink (dest_path); } return ret; }
/** * tmp_picasaweb_upload_async: * * Temporary solution to provide asynchronous uploading and stop * blocking the UI until gdata_picasaweb_service_upload_file_async() * becomes available (bgo #600262). This method does the synchronous * file upload, but is run asynchronously via * g_simple_async_result_run_in_thread(). * * This sets up a minimal #GDataPicasaWebFile entry, using the * basename of the filepath for the file's title (which is not the * caption, but might be something we would consider doing). The * image file and the minimal entry are then uploaded to PicasaWeb's * default album of "Drop Box". In the future, we might consider * adding an Album Chooser to the Preferences/login window, but only * if there's demand. **/ static void tmp_picasaweb_upload_async (GSimpleAsyncResult *result, GObject *source_object, GCancellable *cancellable) { GDataPicasaWebFile *new_file = NULL; XviewerPostasaPlugin *plugin = XVIEWER_POSTASA_PLUGIN (source_object); GDataPicasaWebService *service = plugin->priv->service; GDataPicasaWebFile *file_entry; PicasaWebUploadFileAsyncData *data; #ifdef HAVE_LIBGDATA_0_8 GDataUploadStream *upload_stream; GFileInputStream *in_stream; GFileInfo *file_info; #endif gchar *filename; GError *error = NULL; data = (PicasaWebUploadFileAsyncData*)g_async_result_get_user_data (G_ASYNC_RESULT (result)); /* get filename to set image title */ file_entry = gdata_picasaweb_file_new (NULL); filename = g_file_get_basename (data->imgfile); gdata_entry_set_title (GDATA_ENTRY (file_entry), filename); g_free (filename); #ifdef HAVE_LIBGDATA_0_8 file_info = g_file_query_info (data->imgfile, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, cancellable, &error); if (file_info == NULL) goto got_err; upload_stream = gdata_picasaweb_service_upload_file (service, NULL /* Upload to Dropbox */, file_entry, g_file_info_get_display_name (file_info), g_file_info_get_content_type (file_info), cancellable, &error); g_object_unref (file_info); if (upload_stream == NULL) goto got_err; in_stream = g_file_read (data->imgfile, cancellable, &error); if (in_stream == NULL) { g_object_unref (upload_stream); goto got_err; } if (g_output_stream_splice (G_OUTPUT_STREAM (upload_stream), G_INPUT_STREAM (in_stream), G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, &error) == -1) { g_object_unref (upload_stream); g_object_unref (in_stream); goto got_err; } new_file = gdata_picasaweb_service_finish_file_upload (service, upload_stream, &error); g_object_unref (upload_stream); g_object_unref (in_stream); got_err: /* Jump here if any GIO/GData call doesn't return successfully. * Error handling happens below. */ #else /* libgdata-0.6 */ new_file = gdata_picasaweb_service_upload_file (service, NULL /* Uploading to Drop Box */, file_entry, data->imgfile, cancellable, &error); #endif g_object_unref (file_entry); if (new_file == NULL || error) { if (g_cancellable_is_cancelled (cancellable) == FALSE) { g_simple_async_result_set_from_error (result, error); } /* Clear errors always as cancelling creates errors too */ g_clear_error (&error); } else { g_simple_async_result_set_op_res_gboolean (result, TRUE); } if (new_file != NULL) g_object_unref (new_file); }
static GFile * create_temporary_file (GFile *file, GFileInfo *file_info, GError **in_error) { GInputStream *input_stream; GOutputStream *output_stream; GFile *tmp_file, *parent; gchar *dir, *name, *tmp_path; guint32 mode; gint fd; GError *error = NULL; if (!g_file_is_native (file)) { gchar *uri; uri = g_file_get_uri (file); g_warning ("Could not create temporary file, file is not native: '%s'", uri); g_free (uri); g_set_error (in_error, G_IO_ERROR, G_IO_ERROR_FAILED, "Could not create temporary file, file is not native: '%s'", uri); return NULL; } /* Create input stream */ input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &error)); if (error) { g_critical ("Could not create temporary file, %s", error->message); g_propagate_error (in_error, error); return NULL; } /* Create output stream in a tmp file */ parent = g_file_get_parent (file); dir = g_file_get_path (parent); g_object_unref (parent); name = g_file_get_basename (file); tmp_path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S ".tracker-XXXXXX.%s", dir, name); g_free (dir); g_free (name); mode = g_file_info_get_attribute_uint32 (file_info, G_FILE_ATTRIBUTE_UNIX_MODE); fd = g_mkstemp_full (tmp_path, O_WRONLY, mode); output_stream = g_unix_output_stream_new (fd, TRUE); /* Splice the original file into the tmp file */ g_output_stream_splice (output_stream, input_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, NULL, &error); g_object_unref (output_stream); g_object_unref (input_stream); tmp_file = g_file_new_for_path (tmp_path); g_free (tmp_path); if (error) { g_critical ("Could not copy temporary file, %s", error->message); g_propagate_error (in_error, error); g_file_delete (tmp_file, NULL, NULL); g_object_unref (tmp_file); return NULL; } return tmp_file; }
/** * as_get_yml_data_origin: * * Extract the data origin from the AppStream YAML file. * We don't use the #AsYAMLData loader, because it is much * slower than just loading the initial parts of the file and * extracting the origin manually. */ static gchar* as_get_yml_data_origin (const gchar *fname) { const gchar *data; GZlibDecompressor *zdecomp; g_autoptr(GFileInputStream) fistream = NULL; g_autoptr(GMemoryOutputStream) mem_os = NULL; g_autoptr(GInputStream) conv_stream = NULL; g_autoptr(GFile) file = NULL; g_autofree gchar *str = NULL; g_auto(GStrv) strv = NULL; GError *err; guint i; gchar *start, *end; gchar *origin = NULL; file = g_file_new_for_path (fname); fistream = g_file_read (file, NULL, &err); if (!fistream) { g_critical ("Unable to open file '%s' for reading: %s, skipping.", fname, err->message); g_error_free (err); return NULL; } mem_os = (GMemoryOutputStream*) g_memory_output_stream_new (NULL, 0, g_realloc, g_free); zdecomp = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); conv_stream = g_converter_input_stream_new (G_INPUT_STREAM (fistream), G_CONVERTER (zdecomp)); g_object_unref (zdecomp); g_output_stream_splice (G_OUTPUT_STREAM (mem_os), conv_stream, 0, NULL, NULL); data = (const gchar*) g_memory_output_stream_get_data (mem_os); /* faster than a regular expression? * Get the first YAML document, then extract the origin string. */ if (data == NULL) return NULL; /* start points to the start of the document, i.e. "File:" normally */ start = g_strstr_len (data, 400, YAML_SEPARATOR) + YAML_SEPARATOR_LEN; if (start == NULL) return NULL; /* Find the end of the first document - can be NULL if there is only one, * for example if we're given YAML for an empty archive */ end = g_strstr_len (start, -1, YAML_SEPARATOR); str = g_strndup (start, strlen(start) - (end ? strlen(end) : 0)); strv = g_strsplit (str, "\n", -1); for (i = 0; strv[i] != NULL; i++) { g_auto(GStrv) strv2 = NULL; if (!g_str_has_prefix (strv[i], "Origin:")) continue; strv2 = g_strsplit (strv[i], ":", 2); g_strstrip (strv2[1]); origin = g_strdup (strv2[1]); /* remove quotes, in case the string is quoted */ if ((g_str_has_prefix (origin, "\"")) && (g_str_has_suffix (origin, "\""))) { g_autofree gchar *tmp = NULL; tmp = origin; origin = g_strndup (tmp + 1, strlen (tmp) - 2); } break; } return origin; }
int rpmostree_compose_builtin_sign (int argc, char **argv, GCancellable *cancellable, GError **error) { int exit_status = EXIT_FAILURE; GOptionContext *context = g_option_context_new ("- Use rpm-sign to sign an OSTree commit"); g_autoptr(GFile) repopath = NULL; glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(GFile) tmp_commitdata_file = NULL; g_autoptr(GFileIOStream) tmp_sig_stream = NULL; g_autoptr(GFile) tmp_sig_file = NULL; g_autoptr(GFileIOStream) tmp_commitdata_stream = NULL; GOutputStream *tmp_commitdata_output = NULL; g_autoptr(GInputStream) commit_data = NULL; g_autofree char *checksum = NULL; g_autoptr(GVariant) commit_variant = NULL; g_autoptr(GBytes) commit_bytes = NULL; if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD, cancellable, NULL, error)) goto out; if (!(opt_repo_path && opt_key_id && opt_rev)) { rpmostree_usage_error (context, "Missing required argument", error); goto out; } repopath = g_file_new_for_path (opt_repo_path); repo = ostree_repo_new (repopath); if (!ostree_repo_open (repo, cancellable, error)) goto out; if (!ostree_repo_resolve_rev (repo, opt_rev, FALSE, &checksum, error)) goto out; if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, &commit_variant, error)) goto out; commit_bytes = g_variant_get_data_as_bytes (commit_variant); commit_data = (GInputStream*)g_memory_input_stream_new_from_bytes (commit_bytes); tmp_commitdata_file = g_file_new_tmp ("tmpsigXXXXXX", &tmp_commitdata_stream, error); if (!tmp_commitdata_file) goto out; tmp_commitdata_output = (GOutputStream*)g_io_stream_get_output_stream ((GIOStream*)tmp_commitdata_stream); if (g_output_stream_splice ((GOutputStream*)tmp_commitdata_output, commit_data, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error) < 0) goto out; tmp_sig_file = g_file_new_tmp ("tmpsigoutXXXXXX", &tmp_sig_stream, error); if (!tmp_sig_file) goto out; (void) g_io_stream_close ((GIOStream*)tmp_sig_stream, NULL, NULL); { const char *child_argv[] = { "rpm-sign", "--key", opt_key_id, "--detachsign", gs_file_get_path_cached (tmp_commitdata_file), "--output", gs_file_get_path_cached (tmp_sig_file), NULL }; int estatus; if (!g_spawn_sync (NULL, (char**)child_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, &estatus, error)) goto out; if (!g_spawn_check_exit_status (estatus, error)) goto out; } { char *sigcontent = NULL; gsize len; g_autoptr(GBytes) sigbytes = NULL; if (!g_file_load_contents (tmp_sig_file, cancellable, &sigcontent, &len, NULL, error)) goto out; sigbytes = g_bytes_new_take (sigcontent, len); if (!ostree_repo_append_gpg_signature (repo, checksum, sigbytes, cancellable, error)) goto out; } g_print ("Successfully signed OSTree commit=%s with key=%s\n", checksum, opt_key_id); exit_status = EXIT_SUCCESS; out: if (tmp_commitdata_file) (void) unlink (gs_file_get_path_cached (tmp_commitdata_file)); if (tmp_sig_file) (void) unlink (gs_file_get_path_cached (tmp_sig_file)); return exit_status; }