Ejemplo n.º 1
0
static GFile *
get_g_file_with_encrypted_data (GFileInputStream *in_stream, goffset file_size)
{
    GError *err = NULL;
    GFileIOStream *ostream;
    gssize read_len;
    guchar *buf;
    gsize len_file_data = file_size - SHA512_DIGEST_SIZE;
    gsize done_size = 0;

    GFile *tmp_encrypted_file = g_file_new_tmp (NULL, &ostream, &err);
    if (tmp_encrypted_file == NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return NULL;
    }

    GFileOutputStream *out_enc_stream = g_file_append_to (tmp_encrypted_file, G_FILE_CREATE_NONE, NULL, &err);
    if (out_enc_stream == NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return NULL;
    }

    if (len_file_data < FILE_BUFFER) {
        buf = g_malloc (len_file_data);
        g_input_stream_read (G_INPUT_STREAM (in_stream), buf, len_file_data, NULL, &err);
        g_output_stream_write (G_OUTPUT_STREAM (out_enc_stream), buf, len_file_data, NULL, &err);
    }
    else {
        buf = g_malloc (FILE_BUFFER);
        while (done_size < len_file_data) {
            if ((len_file_data - done_size) > FILE_BUFFER) {
                read_len = g_input_stream_read (G_INPUT_STREAM (in_stream), buf, FILE_BUFFER, NULL, &err);
            }
            else {
                read_len = g_input_stream_read (G_INPUT_STREAM (in_stream), buf, len_file_data - done_size, NULL, &err);
            }
            if (read_len == -1) {
                g_printerr ("%s\n", err->message);
                // TODO
                return NULL;
            }
            g_output_stream_write (G_OUTPUT_STREAM (out_enc_stream), buf, read_len, NULL, &err);
            done_size += read_len;
            memset (buf, 0, FILE_BUFFER);
        }
    }

    g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);
    g_output_stream_close (G_OUTPUT_STREAM (out_enc_stream), NULL, NULL);
    g_object_unref (out_enc_stream);
    g_free (buf);

    return tmp_encrypted_file;
}
Ejemplo n.º 2
0
/**
 * uncompress_bzip2:
 * @name: The name of the file to attempt to decompress
 *
 * Returns: The name of the uncompressed file (in a temporary location) or NULL
 *   free the returned name after use.
 *
 * Also see: http://www.bzip.org/1.0.5/bzip2-manual-1.0.5.html
 */
gchar* uncompress_bzip2 ( gchar *name )
{
#ifdef HAVE_BZLIB_H
	FILE *ff = g_fopen ( name, "r" );
	if ( !ff )
		return NULL;

	int     bzerror;
	BZFILE* bf = BZ2_bzReadOpen ( &bzerror, ff, 0, 0, NULL, 0 ); // This should take care of the bz2 file header
	if ( bzerror != BZ_OK ) {
		BZ2_bzReadClose ( &bzerror, bf );
		// handle error
		return NULL;
	}

	GFileIOStream *gios;
	GError *error = NULL;
	GFile *gf = g_file_new_tmp ( "vik-bz2-tmp.XXXXXX", &gios, &error );
	gchar *tmpname = g_file_get_path (gf);

	GOutputStream *gos = g_io_stream_get_output_stream ( G_IO_STREAM(gios) );

	// Process in arbitary sized chunks
	char buf[4096];
	bzerror = BZ_OK;
	int nBuf;
	// Now process the actual compression data
	while ( bzerror == BZ_OK ) {
		nBuf = BZ2_bzRead ( &bzerror, bf, buf, 4096 );
		if ( bzerror == BZ_OK || bzerror == BZ_STREAM_END) {
			// do something with buf[0 .. nBuf-1]
			if ( g_output_stream_write ( gos, buf, nBuf, NULL, &error ) < 0 ) {
				g_critical ( "Couldn't write bz2 tmp %s file due to %s", tmpname, error->message );
				g_error_free (error);
				BZ2_bzReadClose ( &bzerror, bf );
				goto end;
			}
		}
	}
	if ( bzerror != BZ_STREAM_END ) {
		BZ2_bzReadClose ( &bzerror, bf );
		// handle error...
		goto end;
	} else {
		BZ2_bzReadClose ( &bzerror, bf );
		g_output_stream_close ( gos, NULL, &error );
	}

 end:
	return tmpname;
#else
	return NULL;
#endif
}
Ejemplo n.º 3
0
char *
ot_editor_prompt (OstreeRepo *repo,
                  const char *input,
                  GCancellable *cancellable,
                  GError **error)
{
  glnx_unref_object GSubprocess *proc = NULL;
  g_autoptr(GFile) file = NULL;
  g_autoptr(GFileIOStream) io = NULL;
  GOutputStream *output;
  const char *editor;
  char *ret = NULL;
  g_autofree char *args = NULL;

  editor = get_editor ();
  if (editor == NULL)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "Terminal is dumb, but EDITOR unset");
      goto out;
    }

  file = g_file_new_tmp (NULL, &io, error);
  if (file == NULL)
    goto out;

  output = g_io_stream_get_output_stream (G_IO_STREAM (io));
  if (!g_output_stream_write_all (output, input, strlen (input), NULL, cancellable, error) ||
      !g_io_stream_close (G_IO_STREAM (io), cancellable, error))
    goto out;

  {
    g_autofree char *quoted_file = g_shell_quote (gs_file_get_path_cached (file));
    args = g_strconcat (editor, " ", quoted_file, NULL);
  }

  proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_INHERIT, error, 
                           "/bin/sh", "-c", args, NULL);

  if (!g_subprocess_wait_check (proc, cancellable, error))
    {
      g_prefix_error (error, "There was a problem with the editor '%s'", editor);
      goto out;
    }

  ret = glnx_file_get_contents_utf8_at (AT_FDCWD, gs_file_get_path_cached (file), NULL,
                                        cancellable, error);

out:
  if (file)
    (void )g_file_delete (file, NULL, NULL);
  return ret;
}
Ejemplo n.º 4
0
static gboolean
handle_set_icon_data_url (CockpitAccount *object,
                          GDBusMethodInvocation *invocation,
                          const gchar *arg_data)
{
  GError *error = NULL;
  Account *acc = ACCOUNT (object);

  if (!account_auth_check (object, invocation, acc))
    return TRUE;

  if (acc->u)
    {
      const gchar *base64_data = strstr (arg_data, "base64,");
      if (base64_data == NULL)
        goto out;

      base64_data += strlen ("base64,");

      gsize raw_size;
      gs_free gchar *raw_data = (gchar *)g_base64_decode (base64_data, &raw_size);

      gs_unref_object GFileIOStream *tmp_stream = NULL;
      gs_unref_object GFile *tmp_file = g_file_new_tmp ("cockpit-user-icon-XXXXXX", &tmp_stream, &error);

      if (tmp_file == NULL)
        goto out;

      GOutputStream *out = g_io_stream_get_output_stream (G_IO_STREAM (tmp_stream));
      if (!g_output_stream_write_all (out, raw_data, raw_size, NULL, NULL, &error))
        goto out;

      if (!g_io_stream_close (G_IO_STREAM (tmp_stream), NULL, &error))
        goto out;

      gs_free gchar *tmp_path = g_file_get_path (tmp_file);
      act_user_set_icon_file (acc->u, tmp_path);
      g_file_delete (tmp_file, NULL, NULL);
    }

out:
  if (error)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                                             "%s", error->message);
      g_clear_error (&error);
    }
  else
    cockpit_account_complete_set_icon_data_url (object, invocation);
  return TRUE;
}
Ejemplo n.º 5
0
static void
zpj_download_stream_ready (GObject *source,
                       GAsyncResult *res,
                       gpointer user_data)
{
  GError *error = NULL;
  PdfLoadJob *job = (PdfLoadJob *) user_data;
  const gchar *name;
  const gchar *extension;

  job->stream = zpj_skydrive_download_file_to_stream_finish (ZPJ_SKYDRIVE (source), res, &error);
  if (error != NULL) {
    pdf_load_job_complete_error (job, error);
    return;
  }

  name = zpj_skydrive_entry_get_name (job->zpj_entry);
  extension = gd_filename_get_extension_offset (name);

  /* If it is not a PDF, we need to convert it afterwards.
   * http://msdn.microsoft.com/en-us/library/live/hh826545#fileformats
   */
  if (g_strcmp0 (extension, ".pdf") != 0)
    {
      GFileIOStream *iostream;

      job->download_file = g_file_new_tmp (NULL, &iostream, &error);
      if (error != NULL) {
        pdf_load_job_complete_error (job, error);
        return;
      }

      /* We don't need the iostream. */
      g_io_stream_close (G_IO_STREAM (iostream), NULL, NULL);
    }
  else
    job->download_file = g_file_new_for_path (job->pdf_path);

  g_file_replace_async (job->download_file, NULL, FALSE,
                        G_FILE_CREATE_PRIVATE,
                        G_PRIORITY_DEFAULT,
                        job->cancellable, file_replace_ready_cb,
                        job);
}
Ejemplo n.º 6
0
/**
 * Stream write buffer to a temporary file (in one go)
 *
 * @param buffer The buffer to write
 * @param count Size of the buffer to write
 *
 * @return the filename of the buffer that was written
 */
gchar* util_write_tmp_file_from_bytes ( const void *buffer, gsize count )
{
	GFileIOStream *gios;
	GError *error = NULL;
	gchar *tmpname = NULL;

#if GLIB_CHECK_VERSION(2,32,0)
	GFile *gf = g_file_new_tmp ( "vik-tmp.XXXXXX", &gios, &error );
	tmpname = g_file_get_path (gf);
#else
	gint fd = g_file_open_tmp ( "vik-tmp.XXXXXX", &tmpname, &error );
	if ( error ) {
		g_warning ( "%s", error->message );
		g_error_free ( error );
		return NULL;
	}
	gios = g_file_open_readwrite ( g_file_new_for_path (tmpname), NULL, &error );
	if ( error ) {
		g_warning ( "%s", error->message );
		g_error_free ( error );
		return NULL;
	}
#endif

	gios = g_file_open_readwrite ( g_file_new_for_path (tmpname), NULL, &error );
	if ( error ) {
		g_warning ( "%s", error->message );
		g_error_free ( error );
		return NULL;
	}

	GOutputStream *gos = g_io_stream_get_output_stream ( G_IO_STREAM(gios) );
	if ( g_output_stream_write ( gos, buffer, count, NULL, &error ) < 0 ) {
		g_critical ( "Couldn't write tmp %s file due to %s", tmpname, error->message );
		g_free (tmpname);
		tmpname = NULL;
	}

	g_output_stream_close ( gos, NULL, &error );
	g_object_unref ( gios );

	return tmpname;
}
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;
}
Ejemplo n.º 8
0
/*
 * Write Flac tag, using the level 2 flac interface
 */
gboolean
flac_tag_write_file_tag (const ET_File *ETFile,
                         GError **error)
{
    const File_Tag *FileTag;
    GFile *file;
    GFileIOStream *iostream;
    EtFlacWriteState state;
    FLAC__IOCallbacks callbacks = { et_flac_read_func, et_flac_write_func,
                                    et_flac_seek_func, et_flac_tell_func,
                                    et_flac_eof_func,
                                    et_flac_write_close_func
                                  };
    const gchar *filename;
    const gchar *filename_utf8;
    const gchar *flac_error_msg;
    FLAC__Metadata_Chain *chain;
    FLAC__Metadata_Iterator *iter;
    FLAC__StreamMetadata_VorbisComment_Entry vce_field_vendor_string; // To save vendor string
    gboolean vce_field_vendor_string_found = FALSE;

    g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL, FALSE);
    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

    FileTag       = (File_Tag *)ETFile->FileTag->data;
    filename      = ((File_Name *)ETFile->FileNameCur->data)->value;
    filename_utf8 = ((File_Name *)ETFile->FileNameCur->data)->value_utf8;

    /* libFLAC is able to detect (and skip) ID3v2 tags by itself */

    /* Create a new chain instance to get all blocks in one time. */
    chain = FLAC__metadata_chain_new ();

    if (chain == NULL)
    {
        flac_error_msg = FLAC__Metadata_ChainStatusString[FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR];

        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                     _("Error while opening file ‘%s’ as FLAC: %s"),
                     filename_utf8, flac_error_msg);
        return FALSE;
    }

    file = g_file_new_for_path (filename);

    state.file = file;
    state.error = NULL;
    /* TODO: Fallback to an in-memory copy of the file for non-local files,
     * where creation of the GFileIOStream may fail. */
    iostream = g_file_open_readwrite (file, NULL, &state.error);

    if (iostream == NULL)
    {
        FLAC__metadata_chain_delete (chain);
        g_propagate_error (error, state.error);
        g_object_unref (file);
        return FALSE;
    }

    state.istream = G_FILE_INPUT_STREAM (g_io_stream_get_input_stream (G_IO_STREAM (iostream)));
    state.ostream = G_FILE_OUTPUT_STREAM (g_io_stream_get_output_stream (G_IO_STREAM (iostream)));
    state.seekable = G_SEEKABLE (iostream);
    state.iostream = iostream;

    if (!FLAC__metadata_chain_read_with_callbacks (chain, &state, callbacks))
    {
        const FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status (chain);
        flac_error_msg = FLAC__Metadata_ChainStatusString[status];
        FLAC__metadata_chain_delete (chain);

        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                     _("Error while opening file ‘%s’ as FLAC: %s"),
                     filename_utf8, flac_error_msg);
        et_flac_write_close_func (&state);
        return FALSE;
    }

    /* Create a new iterator instance for the chain. */
    iter = FLAC__metadata_iterator_new ();

    if (iter == NULL)
    {
        flac_error_msg = FLAC__Metadata_ChainStatusString[FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR];

        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                     _("Error while opening file ‘%s’ as FLAC: %s"),
                     filename_utf8, flac_error_msg);
        FLAC__metadata_chain_delete (chain);
        et_flac_write_close_func (&state);
        return FALSE;
    }

    FLAC__metadata_iterator_init (iter, chain);

    while (FLAC__metadata_iterator_next (iter))
    {
        const FLAC__MetadataType block_type = FLAC__metadata_iterator_get_block_type (iter);

        /* TODO: Modify the blocks directly, rather than deleting and
         * recreating. */
        if (block_type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
        {
            // Delete the VORBIS_COMMENT block and convert to padding. But before, save the original vendor string.
            /* Get block data. */
            FLAC__StreamMetadata *block = FLAC__metadata_iterator_get_block(iter);
            FLAC__StreamMetadata_VorbisComment *vc = &block->data.vorbis_comment;

            if (vc->vendor_string.entry != NULL)
            {
                // Get initial vendor string, to don't alterate it by FLAC__VENDOR_STRING when saving file
                vce_field_vendor_string.entry = (FLAC__byte *)g_strdup ((gchar *)vc->vendor_string.entry);
                vce_field_vendor_string.length = strlen ((gchar *)vce_field_vendor_string.entry);
                vce_field_vendor_string_found = TRUE;
            }

            /* Free block data. */
            FLAC__metadata_iterator_delete_block (iter, true);
        }
        else if (block_type == FLAC__METADATA_TYPE_PICTURE)
        {
            /* Delete all the PICTURE blocks, and convert to padding. */
            FLAC__metadata_iterator_delete_block (iter, true);
        }
    }


    //
    // Create and insert a new VORBISCOMMENT block
    //
    {
        FLAC__StreamMetadata *vc_block; // For vorbis comments
        GList *l;

        // Allocate a block for Vorbis comments
        vc_block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);

        // Set the original vendor string, else will be use the version of library
        if (vce_field_vendor_string_found)
        {
            // must set 'copy' param to false, because the API will reuse the  pointer of an empty
            // string (yet still return 'true', indicating it was copied); the string is free'd during
            // metadata_chain_delete routine
            FLAC__metadata_object_vorbiscomment_set_vendor_string(vc_block, vce_field_vendor_string, /*copy=*/false);
        }


        /*********
         * Title *
         *********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_TITLE,
                             FileTag->title,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-title"));

        /**********
         * Artist *
         **********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_ARTIST,
                             FileTag->artist,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-artist"));

        /****************
         * Album Artist *
         ****************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_ALBUM_ARTIST,
                             FileTag->album_artist,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-artist"));

        /*********
         * Album *
         *********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_ALBUM,
                             FileTag->album,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-album"));

        /******************************
         * Disc Number and Disc Total *
         ******************************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_DISC_NUMBER,
                             FileTag->disc_number, FALSE);
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_DISC_TOTAL,
                             FileTag->disc_total, FALSE);

        /********
         * Year *
         ********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_DATE,
                             FileTag->year, FALSE);

        /*************************
         * Track and Total Track *
         *************************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_TRACK_NUMBER,
                             FileTag->track, FALSE);
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_TRACK_TOTAL,
                             FileTag->track_total, FALSE);

        /*********
         * Genre *
         *********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_GENRE,
                             FileTag->genre,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-genre"));

        /***********
         * Comment *
         ***********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_DESCRIPTION,
                             FileTag->comment,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-comment"));

        /************
         * Composer *
         ************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_COMPOSER,
                             FileTag->composer,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-composer"));

        /*******************
         * Original artist *
         *******************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_PERFORMER,
                             FileTag->orig_artist,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-original-artist"));

        /*************
         * Copyright *
         *************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_COPYRIGHT,
                             FileTag->copyright, FALSE);

        /*******
         * URL *
         *******/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_CONTACT,
                             FileTag->url, FALSE);

        /**************
         * Encoded by *
         **************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_ENCODED_BY,
                             FileTag->encoded_by, FALSE);


        /**************************
         * Set unsupported fields *
         **************************/
        for (l = FileTag->other; l != NULL; l = g_list_next (l))
        {
            vc_block_append_other_tag (vc_block, (gchar *)l->data);
        }

        // Add the block to the the chain (so we don't need to free the block)
        FLAC__metadata_iterator_insert_block_after(iter, vc_block);
    }



    //
    // Create and insert PICTURE blocks
    //

    /***********
     * Picture *
     ***********/
    {
        EtPicture *pic = FileTag->picture;

        while (pic)
        {
            /* TODO: Can this ever be NULL? */
            if (pic->bytes)
            {
                const gchar *violation;
                FLAC__StreamMetadata *picture_block; // For picture data
                Picture_Format format;
                gconstpointer data;
                gsize data_size;

                // Allocate block for picture data
                picture_block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE);

                // Type
                picture_block->data.picture.type = pic->type;

                // Mime type
                format = Picture_Format_From_Data(pic);
                /* Safe to pass a const string, according to the FLAC API
                 * reference. */
                FLAC__metadata_object_picture_set_mime_type(picture_block, (gchar *)Picture_Mime_Type_String(format), TRUE);

                // Description
                if (pic->description)
                {
                    FLAC__metadata_object_picture_set_description(picture_block, (FLAC__byte *)pic->description, TRUE);
                }

                // Resolution
                picture_block->data.picture.width  = pic->width;
                picture_block->data.picture.height = pic->height;
                picture_block->data.picture.depth  = 0;

                /* Picture data. */
                data = g_bytes_get_data (pic->bytes, &data_size);
                /* Safe to pass const data, if the last argument (copy) is
                 * TRUE, according the the FLAC API reference. */
                FLAC__metadata_object_picture_set_data (picture_block,
                                                        (FLAC__byte *)data,
                                                        (FLAC__uint32)data_size,
                                                        true);

                if (!FLAC__metadata_object_picture_is_legal (picture_block,
                        &violation))
                {
                    g_critical ("Created an invalid picture block: ‘%s’",
                                violation);
                    FLAC__metadata_object_delete (picture_block);
                }
                else
                {
                    // Add the block to the the chain (so we don't need to free the block)
                    FLAC__metadata_iterator_insert_block_after(iter, picture_block);
                }
            }

            pic = pic->next;
        }
    }

    FLAC__metadata_iterator_delete (iter);

    //
    // Prepare for writing tag
    //

    FLAC__metadata_chain_sort_padding (chain);

    /* Write tag. */
    if (FLAC__metadata_chain_check_if_tempfile_needed (chain, true))
    {
        EtFlacWriteState temp_state;
        GFile *temp_file;
        GFileIOStream *temp_iostream;
        GError *temp_error = NULL;

        temp_file = g_file_new_tmp ("easytag-XXXXXX", &temp_iostream,
                                    &temp_error);

        if (temp_file == NULL)
        {
            FLAC__metadata_chain_delete (chain);
            g_propagate_error (error, temp_error);
            et_flac_write_close_func (&state);
            return FALSE;
        }

        temp_state.file = temp_file;
        temp_state.error = NULL;
        temp_state.istream = G_FILE_INPUT_STREAM (g_io_stream_get_input_stream (G_IO_STREAM (temp_iostream)));
        temp_state.ostream = G_FILE_OUTPUT_STREAM (g_io_stream_get_output_stream (G_IO_STREAM (temp_iostream)));
        temp_state.seekable = G_SEEKABLE (temp_iostream);
        temp_state.iostream = temp_iostream;

        if (!FLAC__metadata_chain_write_with_callbacks_and_tempfile (chain,
                true,
                &state,
                callbacks,
                &temp_state,
                callbacks))
        {
            const FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status (chain);
            flac_error_msg = FLAC__Metadata_ChainStatusString[status];

            FLAC__metadata_chain_delete (chain);
            et_flac_write_close_func (&temp_state);
            et_flac_write_close_func (&state);

            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                         _("Failed to write comments to file ‘%s’: %s"),
                         filename_utf8, flac_error_msg);
            return FALSE;
        }

        if (!g_file_move (temp_file, file, G_FILE_COPY_OVERWRITE, NULL, NULL,
                          NULL, &state.error))
        {
            FLAC__metadata_chain_delete (chain);
            et_flac_write_close_func (&temp_state);

            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                         _("Failed to write comments to file ‘%s’: %s"),
                         filename_utf8, state.error->message);
            et_flac_write_close_func (&state);
            return FALSE;
        }

        et_flac_write_close_func (&temp_state);
    }
    else
    {
        if (!FLAC__metadata_chain_write_with_callbacks (chain, true, &state,
                callbacks))
        {
            const FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status (chain);
            flac_error_msg = FLAC__Metadata_ChainStatusString[status];

            FLAC__metadata_chain_delete (chain);
            et_flac_write_close_func (&state);

            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                         _("Failed to write comments to file ‘%s’: %s"),
                         filename_utf8, flac_error_msg);
            return FALSE;
        }
    }

    FLAC__metadata_chain_delete (chain);
    et_flac_write_close_func (&state);

#ifdef ENABLE_MP3
    {
        // Delete the ID3 tags (create a dummy ETFile for the Id3tag_... function)
        ET_File   *ETFile_tmp    = ET_File_Item_New();
        File_Name *FileName_tmp = et_file_name_new ();
        File_Tag  *FileTag_tmp = et_file_tag_new ();
        // Same file...
        FileName_tmp->value      = g_strdup(filename);
        FileName_tmp->value_utf8 = g_strdup(filename_utf8); // Not necessary to fill 'value_ck'
        ETFile_tmp->FileNameList = g_list_append(NULL,FileName_tmp);
        ETFile_tmp->FileNameCur  = ETFile_tmp->FileNameList;
        // With empty tag...
        ETFile_tmp->FileTagList  = g_list_append(NULL,FileTag_tmp);
        ETFile_tmp->FileTag      = ETFile_tmp->FileTagList;
        id3tag_write_file_tag (ETFile_tmp, NULL);
        ET_Free_File_List_Item(ETFile_tmp);
    }
#endif

    return TRUE;
}
Ejemplo n.º 9
0
static gboolean
_gtr_po_load_ensure_utf8 (GtrPo * po, GError ** error)
{
  GMappedFile *mapped;
  const gchar *content;
  gboolean utf8_valid;
  gchar *filename;
  gsize size;
  GtrPoPrivate *priv = gtr_po_get_instance_private (po);

  filename = g_file_get_path (priv->location);
  mapped = g_mapped_file_new (filename, FALSE, error);
  g_free (filename);

  if (!mapped)
    return FALSE;

  content = g_mapped_file_get_contents (mapped);
  size = g_mapped_file_get_length (mapped);

  utf8_valid = g_utf8_validate (content, size, NULL);

  if (!_gtr_po_load (po, priv->location, error))
    {
      g_mapped_file_unref (mapped);
      return FALSE;
    }

  if (!utf8_valid &&
      priv->header)
    {
      gchar *charset = NULL;

      if (priv->header)
        charset = gtr_header_get_charset (priv->header);

      if (charset && *charset && strcmp (charset, "UTF-8") != 0)
        {
          GOutputStream *converter_stream, *stream;
          GCharsetConverter *converter;
          GIOStream *iostream;
          GFile *tmp;

          /* Store UTF-8 converted file in $TMP */
          converter = g_charset_converter_new ("UTF-8", charset, NULL);

          if (!converter)
            {
              g_set_error (error,
                           GTR_PO_ERROR,
                           GTR_PO_ERROR_ENCODING,
                           _("Could not convert from charset “%s” to UTF-8"),
                           charset);
              g_mapped_file_unref (mapped);
              g_free (charset);
              return FALSE;
            }

          g_free (charset);
          tmp = g_file_new_tmp ("gtranslator-XXXXXX.po",
                                (GFileIOStream **) &iostream,
                                NULL);

          if (!tmp)
            {
              g_set_error (error,
                           GTR_PO_ERROR,
                           GTR_PO_ERROR_ENCODING,
                           _("Could not store temporary "
                             "file for encoding conversion"));
              g_mapped_file_unref (mapped);
              g_object_unref (converter);
              return FALSE;
            }

          stream = g_io_stream_get_output_stream (iostream);
          converter_stream =
            g_converter_output_stream_new (stream,
                                           G_CONVERTER (converter));


          if (!g_output_stream_write_all (converter_stream,
                                          content, size, NULL,
                                          NULL, NULL))
            {
              g_set_error (error,
                           GTR_PO_ERROR,
                           GTR_PO_ERROR_ENCODING,
                           _("Could not store temporary "
                             "file for encoding conversion"));
              g_object_unref (converter_stream);
              g_object_unref (iostream);
              g_object_unref (converter);
              g_mapped_file_unref (mapped);
              return FALSE;
            }

          g_object_unref (converter_stream);
          g_object_unref (iostream);
          g_object_unref (converter);

          /* Now load again the converted file */
          if (!_gtr_po_load (po, tmp, error))
            {
              g_mapped_file_unref (mapped);
              return FALSE;
            }

          /* Ensure Content-Type is set correctly
           * in the header as per the content
           */
          if (priv->header)
            gtr_header_set_charset (priv->header, "UTF-8");

          utf8_valid = TRUE;
        }
    }

  g_mapped_file_unref (mapped);

  if (!utf8_valid)
    {
      g_set_error (error,
                   GTR_PO_ERROR,
                   GTR_PO_ERROR_ENCODING,
                   _("All attempt to convert the file to UTF-8 has failed, "
                     "use the msgconv or iconv command line tools before "
                     "opening this file with GNOME Translation Editor"));
      return FALSE;
    }

  return TRUE;
}
Ejemplo n.º 10
0
static void
remote_query_info_ready_cb (GObject *obj,
                            GAsyncResult *res,
                            gpointer user_data)
{
  PdfLoadJob *job = user_data;
  GError *error = NULL;
  GFile *pdf_file;
  GFileInfo *info;
  const gchar *content_type;
  gchar *tmp_name;
  gchar *tmp_path;

  info = g_file_query_info_finish (G_FILE (obj),
                                   res, &error);

  if (error != NULL) {
    pdf_load_job_complete_error (job, error);
    return;
  }

  job->original_file_mtime =
    g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);

  tmp_name = g_strdup_printf ("gnome-documents-%u.pdf", g_str_hash (job->uri));
  tmp_path = g_build_filename (g_get_user_cache_dir (), "gnome-documents", NULL);
  job->pdf_path =
    g_build_filename (tmp_path, tmp_name, NULL);
  g_mkdir_with_parents (tmp_path, 0700);

  content_type = g_file_info_get_content_type (info);

  if (!content_type_is_native (content_type)) {
    GFileIOStream *iostream;

    job->download_file = g_file_new_tmp (NULL, &iostream, &error);
    if (error != NULL) {
      pdf_load_job_complete_error (job, error);
      return;
    }

    /* We don't need the iostream. */
    g_io_stream_close (G_IO_STREAM (iostream), NULL, NULL);
  } else {
    job->download_file = g_file_new_for_path (job->pdf_path);
  }

  pdf_file = g_file_new_for_path (job->pdf_path);

  g_file_query_info_async (pdf_file,
                           G_FILE_ATTRIBUTE_TIME_MODIFIED,
                           G_FILE_QUERY_INFO_NONE,
                           G_PRIORITY_DEFAULT,
                           job->cancellable,
                           remote_cache_query_info_ready_cb,
                           job);

  g_free (tmp_name);
  g_free (tmp_path);
  g_object_unref (pdf_file);
  g_object_unref (info);
}
Ejemplo n.º 11
0
gboolean
install_bundle (XdgAppDir *dir,
                GOptionContext *context,
                int argc, char **argv,
                GCancellable *cancellable,
                GError **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) deploy_base = NULL;
  g_autoptr(GFile) file = NULL;
  g_autoptr(GFile) gpg_tmp_file = NULL;
  const char *filename;
  g_autofree char *ref = NULL;
  g_autofree char *origin = NULL;
  gboolean created_deploy_base = FALSE;
  gboolean added_remote = FALSE;
  g_autofree char *to_checksum = NULL;
  g_auto(GStrv) parts = NULL;
  g_autoptr(GBytes) gpg_data = NULL;
  g_autofree char *remote = NULL;
  OstreeRepo *repo;
  g_autoptr(OstreeGpgVerifyResult) gpg_result = NULL;
  g_autoptr(GError) my_error = NULL;
  g_auto(GLnxLockFile) lock = GLNX_LOCK_FILE_INIT;

  if (argc < 2)
    return usage_error (context, "bundle filename must be specified", error);

  filename = argv[1];

  repo = xdg_app_dir_get_repo (dir);

  if (!xdg_app_supports_bundles (repo))
    return xdg_app_fail (error, "Your version of ostree is too old to support single-file bundles");

  if (!xdg_app_dir_lock (dir, &lock,
                         cancellable, error))
    goto out;

  file = g_file_new_for_commandline_arg (filename);

  {
    g_autoptr(GVariant) delta = NULL;
    g_autoptr(GVariant) metadata = NULL;
    g_autoptr(GBytes) bytes = NULL;
    g_autoptr(GVariant) to_csum_v = NULL;
    g_autoptr(GVariant) gpg_value = NULL;

    GMappedFile *mfile = g_mapped_file_new (gs_file_get_path_cached (file), FALSE, error);

    if (mfile == NULL)
      return FALSE;

    bytes = g_mapped_file_get_bytes (mfile);
    g_mapped_file_unref (mfile);

    delta = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), bytes, FALSE);
    g_variant_ref_sink (delta);

    to_csum_v = g_variant_get_child_value (delta, 3);
    if (!ostree_validate_structureof_csum_v (to_csum_v, error))
      return FALSE;

    to_checksum = ostree_checksum_from_bytes_v (to_csum_v);

    metadata = g_variant_get_child_value (delta, 0);

    if (!g_variant_lookup (metadata, "ref", "s", &ref))
      return xdg_app_fail (error, "Invalid bundle, no ref in metadata");

    if (!g_variant_lookup (metadata, "origin", "s", &origin))
      origin = NULL;

    gpg_value = g_variant_lookup_value (metadata, "gpg-keys", G_VARIANT_TYPE("ay"));
    if (gpg_value)
      {
        gsize n_elements;
        const char *data = g_variant_get_fixed_array (gpg_value, &n_elements, 1);

        gpg_data = g_bytes_new (data, n_elements);
      }
  }

  parts = xdg_app_decompose_ref (ref, error);
  if (parts == NULL)
    return FALSE;

  deploy_base = xdg_app_dir_get_deploy_dir (dir, ref);
  if (g_file_query_exists (deploy_base, cancellable))
    return xdg_app_fail (error, "%s branch %s already installed", parts[1], parts[3]);

  if (opt_gpg_file != NULL)
    {
      /* Override gpg_data from file */
      gpg_data = read_gpg_data (cancellable, error);
      if (gpg_data == NULL)
        return FALSE;
    }

  /* Add a remote for later updates */
  if (origin != NULL)
    {
      g_auto(GStrv) remotes = ostree_repo_remote_list (repo, NULL);
      int version = 0;

      do
        {
          g_autofree char *name = NULL;
          if (version == 0)
            name = g_strdup_printf ("%s-origin", parts[1]);
          else
            name = g_strdup_printf ("%s-%d-origin", parts[1], version);
          version++;

          if (remotes == NULL ||
              !g_strv_contains ((const char * const *) remotes, name))
            remote = g_steal_pointer (&name);
        }
      while (remote == NULL);
    }

  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
    return FALSE;

  ostree_repo_transaction_set_ref (repo, remote, ref, to_checksum);

  if (!ostree_repo_static_delta_execute_offline (repo,
                                                 file,
                                                 FALSE,
                                                 cancellable,
                                                 error))
    return FALSE;

  if (gpg_data)
    {
      g_autoptr(GFileIOStream) stream;
      GOutputStream *o;

      gpg_tmp_file = g_file_new_tmp (".xdg-app-XXXXXX", &stream, error);
      if (gpg_tmp_file == NULL)
        return FALSE;
      o = g_io_stream_get_output_stream (G_IO_STREAM (stream));
      if (!g_output_stream_write_all (o, g_bytes_get_data (gpg_data, NULL), g_bytes_get_size (gpg_data), NULL, cancellable, error))
        return FALSE;
    }

  gpg_result = ostree_repo_verify_commit_ext (repo,
                                              to_checksum,
                                              NULL, gpg_tmp_file, cancellable, &my_error);

  if (gpg_tmp_file)
    g_file_delete (gpg_tmp_file, cancellable, NULL);

  if (gpg_result == NULL)
    {
      /* NOT_FOUND means no gpg signature, we ignore this *if* there
       * is no gpg key specified in the bundle or by the user */
      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
          gpg_data == NULL)
        g_clear_error (&my_error);
      else
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return FALSE;
        }
    }
  else
    {
      /* If there is no valid gpg signature we fail, unless there is no gpg
         key specified (on the command line or in the file) because then we
         trust the source bundle. */
      if (ostree_gpg_verify_result_count_valid (gpg_result) == 0  &&
          gpg_data != NULL)
        return xdg_app_fail (error, "GPG signatures found, but none are in trusted keyring");
    }

  if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
    return FALSE;

  if (!g_file_make_directory_with_parents (deploy_base, cancellable, error))
    return FALSE;

  /* From here we need to goto out on error, to clean up */
  created_deploy_base = TRUE;

  if (remote)
    {
      g_autoptr(GVariantBuilder) optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
      g_autofree char *basename = g_file_get_basename (file);

      g_variant_builder_add (optbuilder, "{s@v}",
                             "xa.title",
                             g_variant_new_variant (g_variant_new_string (basename)));

      g_variant_builder_add (optbuilder, "{s@v}",
                             "xa.noenumerate",
                             g_variant_new_variant (g_variant_new_boolean (TRUE)));

      g_variant_builder_add (optbuilder, "{s@v}",
                             "xa.prio",
                             g_variant_new_variant (g_variant_new_string ("0")));

      if (!ostree_repo_remote_add (repo,
                                   remote, origin, g_variant_builder_end (optbuilder), cancellable, error))
        goto out;

      added_remote = TRUE;

      if (gpg_data)
        {
          g_autoptr(GInputStream) gpg_data_as_stream = g_memory_input_stream_new_from_bytes (gpg_data);

          if (!ostree_repo_remote_gpg_import (repo, remote, gpg_data_as_stream,
                                              NULL, NULL, cancellable, error))
            goto out;
        }

      if (!xdg_app_dir_set_origin (dir, ref, remote, cancellable, error))
        goto out;
    }

  if (!xdg_app_dir_deploy (dir, ref, to_checksum, cancellable, error))
    goto out;

  if (!xdg_app_dir_make_current_ref (dir, ref, cancellable, error))
    goto out;

  if (strcmp (parts[0], "app") == 0)
    {
      if (!xdg_app_dir_update_exports (dir, parts[1], cancellable, error))
        goto out;
    }

  glnx_release_lock_file (&lock);

  xdg_app_dir_cleanup_removed (dir, cancellable, NULL);

  if (!xdg_app_dir_mark_changed (dir, error))
    goto out;

  ret = TRUE;

 out:
  if (created_deploy_base && !ret)
    gs_shutil_rm_rf (deploy_base, cancellable, NULL);

  if (added_remote && !ret)
    ostree_repo_remote_delete (repo, remote, NULL, NULL);

  return ret;
}
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;
}