Ejemplo n.º 1
0
/**
 * tmpl_template_expand_string:
 * @self: A #TmplTemplate.
 * @scope: (nullable): A #TmplScope or %NULL.
 * @error: A location for a #GError, or %NULL
 *
 * Expands the template and returns the result as a string.
 *
 * Returns: A newly allocated string, or %NULL upon failure.
 */
gchar *
tmpl_template_expand_string (TmplTemplate  *self,
                             TmplScope     *scope,
                             GError       **error)
{
  GOutputStream *stream;
  gchar zero = 0;
  gchar *ret;

  g_return_val_if_fail (TMPL_IS_TEMPLATE (self), NULL);

  stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);

  if (!tmpl_template_expand (self, stream, scope, NULL, error) ||
      !g_output_stream_write_all (stream, &zero, 1, NULL, NULL, error) ||
      !g_output_stream_close (stream, NULL, error))

    {
      g_object_unref (stream);
      return NULL;
    }

  ret = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (stream));

  g_object_unref (stream);

  return ret;
}
Ejemplo n.º 2
0
void
lsm_dom_document_save_to_memory	(LsmDomDocument *document, void **buffer, int *size, GError **error)
{
	GOutputStream *stream;

	if (buffer != NULL)
		*buffer = NULL;
	if (size != NULL)
		*size = 0;

	g_return_if_fail (document != NULL);
	g_return_if_fail (buffer != NULL);

	stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
	if (stream == NULL) {
		*buffer = NULL;
		if (size != NULL)
			*size = 0;
		return;
	}

	lsm_dom_document_save_to_stream (document, G_OUTPUT_STREAM (stream), error);
	g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, error);

	if (size != NULL)
		*size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (stream));
	*buffer = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (stream));

	g_object_unref (stream);
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
GDataInputStream *
http_data_input_stream(GInputStream * stream,gsize * length,GCancellable * cancellable,GError ** error)
{
	GMemoryOutputStream
	* out = G_MEMORY_OUTPUT_STREAM(g_memory_output_stream_new_resizable());
	gchar * content = NULL;
	guint8 byte = 0;
	while(g_input_stream_read(stream,&byte,1,cancellable,error))
	{
		if(g_memory_output_stream_get_data_size(out) > 2048)
		{
			g_output_stream_close(G_OUTPUT_STREAM(out),NULL,NULL);
			g_free(g_memory_output_stream_steal_data(out));
			g_object_unref(out);
			return NULL;
		}
		g_output_stream_write_all(G_OUTPUT_STREAM(out),&byte,1,NULL,NULL,NULL);
		if(g_memory_output_stream_get_data_size(out) >= 4)
		{
			content = g_memory_output_stream_get_data(out);
			if(strncmp((content + g_memory_output_stream_get_data_size(out) - 4),"\r\n\r\n",4) == 0)
				break;
		}
	}
	g_output_stream_close(G_OUTPUT_STREAM(out),NULL,NULL);
	GMemoryInputStream
	* result = G_MEMORY_INPUT_STREAM(g_memory_input_stream_new_from_data(
				g_memory_output_stream_steal_data(out),
				g_memory_output_stream_get_data_size(out),
				g_free
			));
	g_object_unref(out);
	GDataInputStream
	* dis = g_data_input_stream_new(G_INPUT_STREAM(result));
	g_data_input_stream_set_newline_type(dis,G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
	return dis;
}
Ejemplo n.º 5
0
gboolean
ostree_raw_file_to_content_stream (GInputStream       *input,
                                   GFileInfo          *file_info,
                                   GVariant           *xattrs,
                                   GInputStream      **out_input,
                                   guint64            *out_length,
                                   GCancellable       *cancellable,
                                   GError            **error)
{
  gboolean ret = FALSE;
  gpointer header_data;
  gsize header_size;
  ot_lobj GInputStream *ret_input = NULL;
  ot_lvariant GVariant *file_header = NULL;
  ot_lptrarray GPtrArray *streams = NULL;
  ot_lobj GOutputStream *header_out_stream = NULL;
  ot_lobj GInputStream *header_in_stream = NULL;

  file_header = ostree_file_header_new (file_info, xattrs);

  header_out_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);

  if (!ostree_write_variant_with_size (header_out_stream, file_header, 0, NULL, NULL,
                                       cancellable, error))
    goto out;

  if (!g_output_stream_close (header_out_stream, cancellable, error))
    goto out;

  header_size = g_memory_output_stream_get_data_size ((GMemoryOutputStream*) header_out_stream);
  header_data = g_memory_output_stream_steal_data ((GMemoryOutputStream*) header_out_stream);
  header_in_stream = g_memory_input_stream_new_from_data (header_data, header_size, g_free);

  streams = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);

  g_ptr_array_add (streams, g_object_ref (header_in_stream));
  if (input)
    g_ptr_array_add (streams, g_object_ref (input));
  
  ret_input = (GInputStream*)ostree_chain_input_stream_new (streams);

  ret = TRUE;
  ot_transfer_out_value (out_input, &ret_input);
  if (out_length)
    *out_length = header_size + g_file_info_get_size (file_info);
 out:
  return ret;
}
Ejemplo n.º 6
0
static void
gdav_request_splice_cb (GObject *source_object,
                        GAsyncResult *result,
                        gpointer user_data)
{
	SoupMessage *message;
	GTask *task = G_TASK (user_data);
	GError *local_error = NULL;

	message = g_task_get_task_data (task);

	g_output_stream_splice_finish (
		G_OUTPUT_STREAM (source_object), result, &local_error);

	if (local_error != NULL) {
		g_task_return_error (task, local_error);

	/* XXX That the input stream's content is not automatically
	 *     copied to the SoupMessage's response_body is a known
	 *     libsoup bug which may be fixed in a future release.
	 *     Check that the response body is empty so we don't
	 *     accidentally duplicate the body. */
	} else if (message->response_body->data == NULL) {
		GMemoryOutputStream *output_stream;
		gpointer data;
		gsize size;

		output_stream = G_MEMORY_OUTPUT_STREAM (source_object);
		size = g_memory_output_stream_get_data_size (output_stream);
		data = g_memory_output_stream_steal_data (output_stream);

		soup_message_body_append_take (
			message->response_body, data, size);
		soup_message_body_flatten (message->response_body);
		soup_message_finished (message);

		g_task_return_boolean (task, TRUE);
	} else {
		g_task_return_boolean (task, TRUE);
	}

	g_object_unref (task);
}
Ejemplo n.º 7
0
gboolean
builder_host_spawnv (GFile                *dir,
                     char                **output,
                     GError              **error,
                     const gchar * const  *argv)
{
  guint32 client_pid;
  GVariantBuilder *fd_builder = g_variant_builder_new (G_VARIANT_TYPE("a{uh}"));
  GVariantBuilder *env_builder = g_variant_builder_new (G_VARIANT_TYPE("a{ss}"));
  g_autoptr(GUnixFDList) fd_list = g_unix_fd_list_new ();
  gint stdout_handle, stdin_handle, stderr_handle;
  g_autoptr(GDBusConnection) connection = NULL;
  g_autoptr(GVariant) ret = NULL;
  g_autoptr(GMainLoop) loop = NULL;
  g_auto(GStrv) env_vars = NULL;
  guint subscription;
  HostCommandCallData data = { NULL };
  guint sigterm_id = 0, sigint_id = 0;
  g_autofree gchar *commandline = NULL;
  g_autoptr(GOutputStream) out = NULL;
  int pipefd[2];
  int i;

  commandline = flatpak_quote_argv ((const char **) argv);
  g_debug ("Running '%s' on host", commandline);

  connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (connection == NULL)
    return FALSE;

  loop = g_main_loop_new (NULL, FALSE);
  data.connection = connection;
  data.loop = loop;
  data.refs = 1;

  subscription = g_dbus_connection_signal_subscribe (connection,
                                                     NULL,
                                                     "org.freedesktop.Flatpak.Development",
                                                     "HostCommandExited",
                                                     "/org/freedesktop/Flatpak/Development",
                                                     NULL,
                                                     G_DBUS_SIGNAL_FLAGS_NONE,
                                                     host_command_exited_cb,
                                                     &data, NULL);

  stdin_handle = g_unix_fd_list_append (fd_list, 0, error);
  if (stdin_handle == -1)
    return FALSE;

  if (output)
    {
      g_autoptr(GInputStream) in = NULL;

      if (pipe2 (pipefd, O_CLOEXEC) != 0)
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }

      data.refs++;
      in = g_unix_input_stream_new (pipefd[0], TRUE);
      out = g_memory_output_stream_new_resizable ();
      g_output_stream_splice_async (out,
                                    in,
                                    G_OUTPUT_STREAM_SPLICE_NONE,
                                    0,
                                    NULL,
                                    output_spliced_cb,
                                    &data);
      stdout_handle = g_unix_fd_list_append (fd_list, pipefd[1], error);
      close (pipefd[1]);
      if (stdout_handle == -1)
        return FALSE;
    }
  else
    {
      stdout_handle = g_unix_fd_list_append (fd_list, 1, error);
      if (stdout_handle == -1)
        return FALSE;
    }

  stderr_handle = g_unix_fd_list_append (fd_list, 2, error);
  if (stderr_handle == -1)
    return FALSE;

  g_variant_builder_add (fd_builder, "{uh}", 0, stdin_handle);
  g_variant_builder_add (fd_builder, "{uh}", 1, stdout_handle);
  g_variant_builder_add (fd_builder, "{uh}", 2, stderr_handle);

  env_vars = g_listenv ();
  for (i = 0; env_vars[i] != NULL; i++)
    {
      const char *env_var = env_vars[i];
      g_variant_builder_add (env_builder, "{ss}", env_var, g_getenv (env_var));
    }

  sigterm_id = g_unix_signal_add (SIGTERM, sigterm_handler, &data);
  sigint_id = g_unix_signal_add (SIGINT, sigint_handler, &data);

  ret = g_dbus_connection_call_with_unix_fd_list_sync (connection,
                                                       "org.freedesktop.Flatpak",
                                                       "/org/freedesktop/Flatpak/Development",
                                                       "org.freedesktop.Flatpak.Development",
                                                       "HostCommand",
                                                       g_variant_new ("(^ay^aay@a{uh}@a{ss}u)",
                                                                      dir ? flatpak_file_get_path_cached (dir) : "",
                                                                      argv,
                                                                      g_variant_builder_end (fd_builder),
                                                                      g_variant_builder_end (env_builder),
                                                                      FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV),
                                                       G_VARIANT_TYPE ("(u)"),
                                                       G_DBUS_CALL_FLAGS_NONE, -1,
                                                       fd_list, NULL,
                                                       NULL, error);

  if (ret == NULL)
    return FALSE;


  g_variant_get (ret, "(u)", &client_pid);
  data.client_pid = client_pid;

  g_main_loop_run (loop);

  g_source_remove (sigterm_id);
  g_source_remove (sigint_id);
  g_dbus_connection_signal_unsubscribe (connection, subscription);

  if (!g_spawn_check_exit_status (data.exit_status, error))
    return FALSE;

  if (out)
    {
      if (data.splice_error)
        {
          g_propagate_error (error, data.splice_error);
          return FALSE;
        }

      /* Null terminate */
      g_output_stream_write (out, "\0", 1, NULL, NULL);
      g_output_stream_close (out, NULL, NULL);
      *output = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out));
    }

  return TRUE;
}
Ejemplo n.º 8
0
static void
end_element (GMarkupParseContext  *context,
	     const gchar          *element_name,
	     gpointer              user_data,
	     GError              **error)
{
  ParseState *state = user_data;
  GError *my_error = NULL;

  if (strcmp (element_name, "gresource") == 0)
    {
      g_free (state->prefix);
      state->prefix = NULL;
    }

  else if (strcmp (element_name, "file") == 0)
    {
      gchar *file;
      gchar *real_file = NULL;
      gchar *key;
      FileData *data = NULL;
      char *tmp_file = NULL;
      char *tmp_file2 = NULL;

      file = state->string->str;
      key = file;
      if (state->alias)
	key = state->alias;

      if (state->prefix)
	key = g_build_path ("/", "/", state->prefix, key, NULL);
      else
	key = g_build_path ("/", "/", key, NULL);

      if (g_hash_table_lookup (state->table, key) != NULL)
	{
	  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
		       _("File %s appears multiple times in the resource"),
		       key);
	  return;
	}

      if (sourcedirs != NULL)
        {
	  real_file = find_file (file);
	  if (real_file == NULL && state->collect_data)
	    {
		g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
			     _("Failed to locate “%s” in any source directory"), file);
		return;
	    }
	}
      else
        {
	  gboolean exists;
	  exists = g_file_test (file, G_FILE_TEST_EXISTS);
	  if (!exists && state->collect_data)
	    {
	      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
			   _("Failed to locate “%s” in current directory"), file);
	      return;
	    }
	}

      if (real_file == NULL)
        real_file = g_strdup (file);

      data = g_new0 (FileData, 1);
      data->filename = g_strdup (real_file);
      if (!state->collect_data)
        goto done;

      if (state->preproc_options)
        {
          gchar **options;
          guint i;
          gboolean xml_stripblanks = FALSE;
          gboolean to_pixdata = FALSE;

          options = g_strsplit (state->preproc_options, ",", -1);

          for (i = 0; options[i]; i++)
            {
              if (!strcmp (options[i], "xml-stripblanks"))
                xml_stripblanks = TRUE;
              else if (!strcmp (options[i], "to-pixdata"))
                to_pixdata = TRUE;
              else
                {
                  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                               _("Unknown processing option “%s”"), options[i]);
                  g_strfreev (options);
                  goto cleanup;
                }
            }
          g_strfreev (options);

          if (xml_stripblanks && xmllint != NULL)
            {
              int fd;
	      GSubprocess *proc;

              tmp_file = g_strdup ("resource-XXXXXXXX");
              if ((fd = g_mkstemp (tmp_file)) == -1)
                {
                  int errsv = errno;

                  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                               _("Failed to create temp file: %s"),
                              g_strerror (errsv));
                  g_free (tmp_file);
                  tmp_file = NULL;
                  goto cleanup;
                }
              close (fd);

              proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error,
                                       xmllint, "--nonet", "--noblanks", "--output", tmp_file, real_file, NULL);
              g_free (real_file);
	      real_file = NULL;

	      if (!proc)
		goto cleanup;

	      if (!g_subprocess_wait_check (proc, NULL, error))
		{
		  g_object_unref (proc);
                  goto cleanup;
                }

	      g_object_unref (proc);

              real_file = g_strdup (tmp_file);
            }

          if (to_pixdata)
            {
              int fd;
	      GSubprocess *proc;

              if (gdk_pixbuf_pixdata == NULL)
                {
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                       "to-pixbuf preprocessing requested but GDK_PIXBUF_PIXDATA "
                                       "not set and gdk-pixbuf-pixdata not found in path");
                  goto cleanup;
                }

              tmp_file2 = g_strdup ("resource-XXXXXXXX");
              if ((fd = g_mkstemp (tmp_file2)) == -1)
                {
                  int errsv = errno;

                  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                               _("Failed to create temp file: %s"),
			       g_strerror (errsv));
                  g_free (tmp_file2);
                  tmp_file2 = NULL;
                  goto cleanup;
                }
              close (fd);

              proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error,
                                       gdk_pixbuf_pixdata, real_file, tmp_file2, NULL);
              g_free (real_file);
              real_file = NULL;

	      if (!g_subprocess_wait_check (proc, NULL, error))
		{
		  g_object_unref (proc);
                  goto cleanup;
		}

	      g_object_unref (proc);

              real_file = g_strdup (tmp_file2);
            }
	}

      if (!g_file_get_contents (real_file, &data->content, &data->size, &my_error))
	{
	  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
		       _("Error reading file %s: %s"),
		       real_file, my_error->message);
	  g_clear_error (&my_error);
	  goto cleanup;
	}
      /* Include zero termination in content_size for uncompressed files (but not in size) */
      data->content_size = data->size + 1;

      if (state->compressed)
	{
	  GOutputStream *out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
	  GZlibCompressor *compressor =
	    g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9);
	  GOutputStream *out2 = g_converter_output_stream_new (out, G_CONVERTER (compressor));

	  if (!g_output_stream_write_all (out2, data->content, data->size,
					  NULL, NULL, NULL) ||
	      !g_output_stream_close (out2, NULL, NULL))
	    {
	      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			   _("Error compressing file %s"),
			   real_file);
	      goto cleanup;
	    }

	  g_free (data->content);
	  data->content_size = g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (out));
	  data->content = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out));

	  g_object_unref (compressor);
	  g_object_unref (out);
	  g_object_unref (out2);

	  data->flags |= G_RESOURCE_FLAGS_COMPRESSED;
	}

done:
      g_hash_table_insert (state->table, key, data);
      data = NULL;

    cleanup:
      /* Cleanup */

      g_free (state->alias);
      state->alias = NULL;
      g_string_free (state->string, TRUE);
      state->string = NULL;
      g_free (state->preproc_options);
      state->preproc_options = NULL;

      g_free (real_file);

      if (tmp_file)
        {
          unlink (tmp_file);
          g_free (tmp_file);
        }

      if (tmp_file2)
        {
          unlink (tmp_file2);
          g_free (tmp_file2);
        }

      if (data != NULL)
        file_data_free (data);
    }
}
Ejemplo n.º 9
0
static void
end_element (GMarkupParseContext  *context,
	     const gchar          *element_name,
	     gpointer              user_data,
	     GError              **error)
{
  ParseState *state = user_data;
  GError *my_error = NULL;

  if (strcmp (element_name, "gresource") == 0)
    {
      g_free (state->prefix);
      state->prefix = NULL;
    }

  else if (strcmp (element_name, "file") == 0)
    {
      gchar *file, *real_file;
      gchar *key;
      FileData *data;
      char *tmp_file = NULL;
      char *tmp_file2 = NULL;

      file = state->string->str;
      key = file;
      if (state->alias)
	key = state->alias;

      if (state->prefix)
	key = g_build_path ("/", "/", state->prefix, key, NULL);
      else
	key = g_build_path ("/", "/", key, NULL);

      if (g_hash_table_lookup (state->table, key) != NULL)
	{
	  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
		       _("File %s appears multiple times in the resource"),
		       key);
	  return;
	}

      data = g_new0 (FileData, 1);

      if (sourcedirs != NULL)
        {
	  real_file = find_file (file);
	  if (real_file == NULL)
	    {
		g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
			     _("Failed to locate '%s' in any source directory"), file);
		return;
	    }
	}
      else
        {
	  gboolean exists;
	  exists = g_file_test (file, G_FILE_TEST_EXISTS);
	  if (!exists)
	    {
	      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
			   _("Failed to locate '%s' in current directory"), file);
	      return;
	    }
	  real_file = g_strdup (file);
	}

      data->filename = g_strdup (real_file);
      if (!state->collect_data)
        goto done;

      if (state->preproc_options)
        {
          gchar **options;
          guint i;
          gboolean xml_stripblanks = FALSE;
          gboolean to_pixdata = FALSE;

          options = g_strsplit (state->preproc_options, ",", -1);

          for (i = 0; options[i]; i++)
            {
              if (!strcmp (options[i], "xml-stripblanks"))
                xml_stripblanks = TRUE;
              else if (!strcmp (options[i], "to-pixdata"))
                to_pixdata = TRUE;
              else
                {
                  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                               _("Unknown processing option \"%s\""), options[i]);
                  g_strfreev (options);
                  goto cleanup;
                }
            }
          g_strfreev (options);

          if (xml_stripblanks && xmllint != NULL)
            {
              gchar *argv[8];
              int status, fd, argc;

              tmp_file = g_strdup ("resource-XXXXXXXX");
              if ((fd = g_mkstemp (tmp_file)) == -1)
                {
                  int errsv = errno;

                  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                               _("Failed to create temp file: %s"),
                              g_strerror (errsv));
                  g_free (tmp_file);
                  tmp_file = NULL;
                  goto cleanup;
                }
              close (fd);

              argc = 0;
              argv[argc++] = (gchar *) xmllint;
              argv[argc++] = "--nonet";
              argv[argc++] = "--noblanks";
              argv[argc++] = "--output";
              argv[argc++] = tmp_file;
              argv[argc++] = real_file;
              argv[argc++] = NULL;
              g_assert (argc <= G_N_ELEMENTS (argv));

              if (!g_spawn_sync (NULL /* cwd */, argv, NULL /* envv */,
                                 G_SPAWN_STDOUT_TO_DEV_NULL |
                                 G_SPAWN_STDERR_TO_DEV_NULL,
                                 NULL, NULL, NULL, NULL, &status, &my_error))
                {
                  g_propagate_error (error, my_error);
                  goto cleanup;
                }
#ifdef HAVE_SYS_WAIT_H
              if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
                {
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                      _("Error processing input file with xmllint"));
                  goto cleanup;
                }
#endif

              g_free (real_file);
              real_file = g_strdup (tmp_file);
            }

          if (to_pixdata)
            {
              gchar *argv[4];
              int status, fd, argc;

              if (gdk_pixbuf_pixdata == NULL)
                {
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                       "to-pixbuf preprocessing requested but GDK_PIXBUF_PIXDATA "
                                       "not set and gdk-pixbuf-pixdata not found in path");
                  goto cleanup;
                }

              tmp_file2 = g_strdup ("resource-XXXXXXXX");
              if ((fd = g_mkstemp (tmp_file2)) == -1)
                {
                  int errsv = errno;

                  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                               _("Failed to create temp file: %s"),
			       g_strerror (errsv));
                  g_free (tmp_file2);
                  tmp_file2 = NULL;
                  goto cleanup;
                }
              close (fd);

              argc = 0;
              argv[argc++] = (gchar *) gdk_pixbuf_pixdata;
              argv[argc++] = real_file;
              argv[argc++] = tmp_file2;
              argv[argc++] = NULL;
              g_assert (argc <= G_N_ELEMENTS (argv));

              if (!g_spawn_sync (NULL /* cwd */, argv, NULL /* envv */,
                                 G_SPAWN_STDOUT_TO_DEV_NULL |
                                 G_SPAWN_STDERR_TO_DEV_NULL,
                                 NULL, NULL, NULL, NULL, &status, &my_error))
                {
                  g_propagate_error (error, my_error);
                  goto cleanup;
                }
#ifdef HAVE_SYS_WAIT_H
              if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
                {
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
				       _("Error processing input file with to-pixdata"));
                  goto cleanup;
                }
#endif

              g_free (real_file);
              real_file = g_strdup (tmp_file2);
            }
	}

      if (!g_file_get_contents (real_file, &data->content, &data->size, &my_error))
	{
	  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
		       _("Error reading file %s: %s"),
		       real_file, my_error->message);
	  g_clear_error (&my_error);
	  goto cleanup;
	}
      /* Include zero termination in content_size for uncompressed files (but not in size) */
      data->content_size = data->size + 1;

      if (state->compressed)
	{
	  GOutputStream *out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
	  GZlibCompressor *compressor =
	    g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9);
	  GOutputStream *out2 = g_converter_output_stream_new (out, G_CONVERTER (compressor));

	  if (!g_output_stream_write_all (out2, data->content, data->size,
					  NULL, NULL, NULL) ||
	      !g_output_stream_close (out2, NULL, NULL))
	    {
	      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			   _("Error compressing file %s"),
			   real_file);
	      goto cleanup;
	    }

	  g_free (data->content);
	  data->content_size = g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (out));
	  data->content = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out));

	  g_object_unref (compressor);
	  g_object_unref (out);
	  g_object_unref (out2);

	  data->flags |= G_RESOURCE_FLAGS_COMPRESSED;
	}

    done:

      g_hash_table_insert (state->table, key, data);

    cleanup:
      /* Cleanup */

      g_free (state->alias);
      state->alias = NULL;
      g_string_free (state->string, TRUE);
      state->string = NULL;
      g_free (state->preproc_options);
      state->preproc_options = NULL;

      g_free (real_file);

      if (tmp_file)
        {
          unlink (tmp_file);
          g_free (tmp_file);
        }

      if (tmp_file2)
        {
          unlink (tmp_file2);
          g_free (tmp_file2);
        }
    }
}
Ejemplo n.º 10
0
static gboolean
archive_spawnv (GFile                *dir,
                char                **output,
                GError              **error,
                const gchar * const  *argv)
{
  g_autoptr(GSubprocessLauncher) launcher = NULL;
  g_autoptr(GSubprocess) subp = NULL;
  GInputStream *in;
  g_autoptr(GOutputStream) out = NULL;
  g_autoptr(GMainLoop) loop = NULL;
  SpawnData data = {0};
  g_autofree gchar *commandline = NULL;

  launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);

  if (output)
    g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE);

  if (dir)
    {
      g_autofree char *path = g_file_get_path (dir);
      g_subprocess_launcher_set_cwd (launcher, path);
    }

  commandline = g_strjoinv (" ", (gchar **) argv);
  g_debug ("Running '%s'", commandline);

  subp = g_subprocess_launcher_spawnv (launcher, argv, error);

  if (subp == NULL)
    return FALSE;

  loop = g_main_loop_new (NULL, FALSE);

  data.loop = loop;
  data.refs = 1;

  if (output)
    {
      data.refs++;
      in = g_subprocess_get_stdout_pipe (subp);
      out = g_memory_output_stream_new_resizable ();
      g_output_stream_splice_async (out,
                                    in,
                                    G_OUTPUT_STREAM_SPLICE_NONE,
                                    0,
                                    NULL,
                                    spawn_output_spliced_cb,
                                    &data);
    }

  g_subprocess_wait_async (subp, NULL, spawn_exit_cb, &data);

  g_main_loop_run (loop);

  if (data.error)
    {
      g_propagate_error (error, data.error);
      g_clear_error (&data.splice_error);
      return FALSE;
    }

  if (out)
    {
      if (data.splice_error)
        {
          g_propagate_error (error, data.splice_error);
          return FALSE;
        }

      /* Null terminate */
      g_output_stream_write (out, "\0", 1, NULL, NULL);
      g_output_stream_close (out, NULL, NULL);
      *output = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out));
    }

  return TRUE;
}