IOChannel::IOChannel(const String& filePath, Type type)
    : m_path(filePath)
    , m_type(type)
{
    auto path = WebCore::fileSystemRepresentation(filePath);
    GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(path.data()));
    switch (m_type) {
    case Type::Create: {
        g_file_delete(file.get(), nullptr, nullptr);
        m_outputStream = adoptGRef(G_OUTPUT_STREAM(g_file_create(file.get(), static_cast<GFileCreateFlags>(G_FILE_CREATE_PRIVATE), nullptr, nullptr)));
        ASSERT(m_outputStream);
        GUniquePtr<char> birthtimeString(g_strdup_printf("%" G_GUINT64_FORMAT, std::chrono::system_clock::to_time_t(std::chrono::system_clock::now())));
        g_file_set_attribute_string(file.get(), "xattr::birthtime", birthtimeString.get(), G_FILE_QUERY_INFO_NONE, nullptr, nullptr);
        break;
    }
    case Type::Write: {
        m_ioStream = adoptGRef(g_file_open_readwrite(file.get(), nullptr, nullptr));
        ASSERT(m_ioStream);
        break;
    }
    case Type::Read:
        m_inputStream = adoptGRef(G_INPUT_STREAM(g_file_read(file.get(), nullptr, nullptr)));
        ASSERT(m_inputStream);
        break;
    }
}
Beispiel #2
0
PlatformFileHandle openFile(const String& path, FileOpenMode mode)
{
    GUniquePtr<gchar> filename = unescapedFilename(path);
    if (!filename)
        return invalidPlatformFileHandle;

    GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(filename.get()));
    GFileIOStream* ioStream = 0;
    if (mode == OpenForRead)
        ioStream = g_file_open_readwrite(file.get(), 0, 0);
    else if (mode == OpenForWrite) {
        if (g_file_test(filename.get(), static_cast<GFileTest>(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)))
            ioStream = g_file_open_readwrite(file.get(), 0, 0);
        else
            ioStream = g_file_create_readwrite(file.get(), G_FILE_CREATE_NONE, 0, 0);
    }

    return ioStream;
}
Beispiel #3
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;
}
Beispiel #4
0
static void * gio_fopen (const char * filename, const char * mode)
{
    GError * error = 0;

    FileData * data = g_new0 (FileData, 1);

    data->file = g_file_new_for_uri (filename);

    switch (mode[0])
    {
    case 'r':
        if (strchr (mode, '+'))
        {
            data->iostream = (GIOStream *) g_file_open_readwrite (data->file, 0, & error);
            CHECK_ERROR ("open", filename);
            data->istream = g_io_stream_get_input_stream (data->iostream);
            data->ostream = g_io_stream_get_output_stream (data->iostream);
            data->seekable = (GSeekable *) data->iostream;
        }
        else
        {
            data->istream = (GInputStream *) g_file_read (data->file, 0, & error);
            CHECK_ERROR ("open", filename);
            data->seekable = (GSeekable *) data->istream;
        }
        break;
    case 'w':
        if (strchr (mode, '+'))
        {
            data->iostream = (GIOStream *) g_file_replace_readwrite (data->file, 0, 0, 0, 0, & error);
            CHECK_ERROR ("open", filename);
            data->istream = g_io_stream_get_input_stream (data->iostream);
            data->ostream = g_io_stream_get_output_stream (data->iostream);
            data->seekable = (GSeekable *) data->iostream;
        }
        else
        {
            data->ostream = (GOutputStream *) g_file_replace (data->file, 0, 0, 0, 0, & error);
            CHECK_ERROR ("open", filename);
            data->seekable = (GSeekable *) data->ostream;
        }
        break;
    case 'a':
        if (strchr (mode, '+'))
        {
            gio_error ("Cannot open %s: GIO does not support read-and-append mode.", filename);
            goto FAILED;
        }
        else
        {
            data->ostream = (GOutputStream *) g_file_append_to (data->file, 0, 0, & error);
            CHECK_ERROR ("open", filename);
            data->seekable = (GSeekable *) data->ostream;
        }
        break;
    default:
        gio_error ("Cannot open %s: invalid mode.", filename);
        goto FAILED;
    }

    return data;

FAILED:
    g_free (data);
    return 0;
}
Beispiel #5
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;
}
static GObject *
gegl_tile_backend_file_constructor (GType                  type,
                                    guint                  n_params,
                                    GObjectConstructParam *params)
{
  GObject             *object;
  GeglTileBackendFile *self;
  GeglTileBackend     *backend;

  object  = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
  self    = GEGL_TILE_BACKEND_FILE (object);
  backend = GEGL_TILE_BACKEND (object);

  GEGL_NOTE (GEGL_DEBUG_TILE_BACKEND, "constructing file backend: %s", self->path);
#if HAVE_GIO
  self->file = g_file_new_for_commandline_arg (self->path);
#else
  self->i = self->o = -1;
#endif
  self->index = g_hash_table_new (gegl_tile_backend_file_hashfunc, gegl_tile_backend_file_equalfunc);


  /* If the file already exists open it, assuming it is a GeglBuffer. */
#if HAVE_GIO
  if (g_file_query_exists (self->file, NULL))
#else
  if (access (self->path, F_OK) != -1)
#endif
    {
      goffset offset = 0;

#if HAVE_GIO
      /* Install a monitor for changes to the file in case other applications
       * might be writing to the buffer
       */
      self->monitor = g_file_monitor_file (self->file, G_FILE_MONITOR_NONE,
                                           NULL, NULL);
      g_signal_connect (self->monitor, "changed",
                        G_CALLBACK (gegl_tile_backend_file_file_changed),
                        self);

      {
        GError *error = NULL;
        self->io = G_IO_STREAM (g_file_open_readwrite (self->file, NULL, &error));
        if (error)
          {
            /* Try again but this time with only read access. This is
             * a quick-fix for make distcheck, where img_cmp fails
             * when it opens a GeglBuffer file in the source tree
             * (which is read-only).
             */
            g_error_free (error);
            error = NULL;
            self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, &error));

            if (error)
              {
                g_warning ("%s: %s", G_STRLOC, error->message);
                g_error_free (error);
                error = NULL;
              }
          }
        else
          {
            self->o = g_io_stream_get_output_stream (self->io);
            self->i = g_io_stream_get_input_stream (self->io);
          }
      }

#else
      self->o = open (self->path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
      self->i = dup (self->o);
#endif
      /*self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));*/
      self->header = gegl_buffer_read_header (self->i, &offset)->header;
      self->header.rev = self->header.rev -1;

      /* we are overriding all of the work of the actual constructor here,
       * a really evil hack :d
       */
      backend->priv->tile_width = self->header.tile_width;
      backend->priv->tile_height = self->header.tile_height;
      backend->priv->format = babl_format (self->header.description);
      backend->priv->px_size = babl_format_get_bytes_per_pixel (backend->priv->format);
      backend->priv->tile_size = backend->priv->tile_width *
                                    backend->priv->tile_height *
                                    backend->priv->px_size;

      /* insert each of the entries into the hash table */
      gegl_tile_backend_file_load_index (self, TRUE);
      self->exist = TRUE;
#if HAVE_GIO
      /* We can only assert input stream, we won't have an output
       * stream on read-only files
       */
      g_assert (self->i);
#else
      g_assert (self->i != -1);
      g_assert (self->o != -1);
#endif

      /* to autoflush gegl_buffer_set */

      /* XXX: poking at internals, icky */
      backend->priv->shared = TRUE;
    }
  else
    {
      self->exist = FALSE; /* this is also the default, the file will be created on demand */
    }

#if HAVE_GIO
  g_assert (self->file);
#endif

  backend->priv->header = &self->header;

  return object;
}
static void
gegl_tile_backend_file_ensure_exist (GeglTileBackendFile *self)
{
  if (!self->exist)
    {
      GeglTileBackend *backend;
#if HAVE_GIO
      GError *error = NULL;

      if (self->io)
        {
          g_print ("we already existed\n");
          return;
        }
#endif
      self->exist = TRUE;

      backend = GEGL_TILE_BACKEND (self);

      GEGL_NOTE (GEGL_DEBUG_TILE_BACKEND, "creating swapfile  %s", self->path);

#if HAVE_GIO
      self->o = G_OUTPUT_STREAM (g_file_replace (self->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
      g_output_stream_flush (self->o, NULL, NULL);
      g_output_stream_close (self->o, NULL, NULL);

      self->io = G_IO_STREAM (g_file_open_readwrite (self->file, NULL, &error));
      if (error)
        {
          g_warning ("%s: %s", G_STRLOC, error->message);
          g_error_free (error);
          error = NULL;
        }
      self->o = g_io_stream_get_output_stream (self->io);
      self->i = g_io_stream_get_input_stream (self->io);

#else
      self->o = open (self->path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
#endif

      self->next_pre_alloc = 256;  /* reserved space for header */
      self->total          = 256;  /* reserved space for header */
#if HAVE_GIO
      g_assert(g_seekable_seek (G_SEEKABLE (self->o), 256, G_SEEK_SET, NULL, NULL));
#endif
      gegl_buffer_header_init (&self->header,
                               backend->priv->tile_width,
                               backend->priv->tile_height,
                               backend->priv->px_size,
                               backend->priv->format
                               );
      gegl_tile_backend_file_write_header (self);
#if HAVE_GIO
      g_output_stream_flush (self->o, NULL, NULL);
#else
      fsync (self->o);
      self->i = dup (self->o);
#endif

      /*self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));*/
      self->next_pre_alloc = 256;  /* reserved space for header */
      self->total          = 256;  /* reserved space for header */
#if HAVE_GIO
      g_assert (self->io);
      g_assert (self->i);
      g_assert (self->o);
#else
      g_assert (self->i != -1);
      g_assert (self->o != -1);
#endif
    }
}
Beispiel #8
0
    bool verify_and_strip_signatures()
    {
        g_debug( "CHECKING SIGNATURE(S)" );

        Signature::Info::List signatures;

        gsize signature_length = 0;

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

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

        unsigned int found = 0;

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

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

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

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

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

            return false;
        }

        // If there were no signatures, we are done

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

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

        bool result = false;

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

        if ( file )
        {

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

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

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

                        file_size -= signature_length;

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

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

                g_object_unref( G_OBJECT( stream ) );
            }

            g_object_unref( G_OBJECT( file ) );
        }

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

        return result;
    }
Beispiel #9
0
gboolean
wavpack_tag_write_file_tag (const ET_File *ETFile,
                            GError **error)
{
    WavpackStreamReader writer = { wavpack_read_bytes, wavpack_get_pos,
                                   wavpack_set_pos_abs, wavpack_set_pos_rel,
                                   wavpack_push_back_byte, wavpack_get_length,
                                   wavpack_can_seek, wavpack_write_bytes };
    GFile *file;
    EtWavpackWriteState state;
    const gchar *filename;
    const File_Tag *FileTag;
    WavpackContext *wpc;
    gchar message[80];
    gchar *buffer;

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

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

    file = g_file_new_for_path (filename);
    state.error = NULL;
    state.iostream = g_file_open_readwrite (file, NULL, &state.error);
    g_object_unref (file);

    if (!state.iostream)
    {
        g_propagate_error (error, state.error);
        return FALSE;
    }

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

    /* NULL for the WavPack correction file. */
    wpc = WavpackOpenFileInputEx (&writer, &state, NULL, message,
                                  OPEN_EDIT_TAGS, 0);

    if (wpc == NULL)
    {
        if (state.error)
        {
            g_propagate_error (error, state.error);
        }
        else
        {
            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
                         message);
        }

        g_object_unref (state.iostream);
        return FALSE;
    }

    /* Title. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "title", FileTag->title))
    {
        goto err;
    }

    /* Artist. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "artist", FileTag->artist))
    {
        goto err;
    }

    /* Album artist. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "album artist",
                                               FileTag->album_artist))
    {
        goto err;
    }

    /* Album. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "album", FileTag->album))
    {
        goto err;
    }

    /* Discnumber. */
    if (FileTag->disc_number && FileTag->disc_total)
    {
        buffer = g_strdup_printf ("%s/%s", FileTag->disc_number,
                                  FileTag->disc_total);

        if (!et_wavpack_append_or_delete_tag_item (wpc, "part", buffer))
        {
            g_free (buffer);
            goto err;
        }
        else
        {
            g_free (buffer);
        }
    }
    else
    {
        if (!et_wavpack_append_or_delete_tag_item (wpc, "part",
                                                   FileTag->disc_number))
        {
            goto err;
        }
    }

    /* Year. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "year", FileTag->year))
    {
        goto err;
    }

    /* Tracknumber + tracktotal. */
    if (FileTag->track_total)
    {
        buffer = g_strdup_printf ("%s/%s", FileTag->track,
                                  FileTag->track_total);

        if (!et_wavpack_append_or_delete_tag_item (wpc, "track", buffer))
        {
            g_free (buffer);
            goto err;
        }
        else
        {
            g_free (buffer);
        }
    }
    else
    {
        if (!et_wavpack_append_or_delete_tag_item (wpc, "track",
                                                   FileTag->track))
        {
            goto err;
        }
    }

    /* Genre. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "genre", FileTag->genre))
    {
        goto err;
    }

    /* Comment. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "comment", FileTag->comment))
    {
        goto err;
    }

    /* Composer. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "composer",
                                               FileTag->composer))
    {
        goto err;
    }

    /* Original artist. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "original artist",
                                               FileTag->orig_artist))
    {
        goto err;
    }

    /* Copyright. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "copyright",
                                               FileTag->copyright))
    {
        goto err;
    }

    /* URL. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "copyright url",
                                               FileTag->url))
    {
        goto err;
    }

    /* Encoded by. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "encoded by",
                                               FileTag->encoded_by))
    {
        goto err;
    }

    if (WavpackWriteTag (wpc) == 0)
    {
        goto err;
    }

    WavpackCloseFile (wpc);

    g_object_unref (state.iostream);

    return TRUE;

err:
    g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
                 WavpackGetErrorMessage (wpc));
    WavpackCloseFile (wpc);
    return FALSE;
}
Beispiel #10
0
static void
_completion_update_text(GFile *file, const gchar *text)
{
	gchar *path;
	GFileIOStream *file_stream;
	GInputStream *in_stream;
	GOutputStream *out_stream;
	gchar buffer[block_size];
	const gchar *ptr;
	GError *err = NULL;
	gboolean found = FALSE;
	gint32 counter = 0;
	gssize size;

	g_assert(file != NULL);
	g_assert(text != NULL);

	path = g_file_get_path(file);

	g_debug("Opening file (rw): \"%s\"", path);

	if((file_stream = g_file_open_readwrite(file, NULL, &err)))
	{
		/* search for given text */
		g_debug("Searching text...");
		in_stream = g_io_stream_get_input_stream(G_IO_STREAM(file_stream));
		out_stream = g_io_stream_get_output_stream(G_IO_STREAM(file_stream));

		do
		{
			if((size = g_input_stream_read(in_stream, buffer, block_size, NULL, &err)) == block_size)
			{
				ptr = buffer + COMPLETION_COUNTER_SIZE;
				g_debug("Found text: \"%s\"", ptr);

				if(!strcmp(ptr, text))
				{
					found = TRUE;

					/* update counter */
					memcpy(&counter, buffer, COMPLETION_COUNTER_SIZE);

					if(counter != G_MAXINT32)
					{
						counter++;
					}

					g_debug("updating counter: %d", counter);

					if(g_seekable_seek(G_SEEKABLE(out_stream), -block_size, G_SEEK_CUR, NULL, &err))
					{
						g_output_stream_write(out_stream, &counter, COMPLETION_COUNTER_SIZE, NULL, &err);
					}
					else
					{
						g_warning("g_seekable_seek() failed");
					}
				}
			}
			else
			{
				if(size)
				{
					g_warning("Invalid block size: %d", size);
				}
			}
		} while(!err && !found && size);

		if(!found)
		{
			/* append text to file */
			g_debug("Appending new text: \"%s\"", text);

			memset(buffer, 0, block_size);
			memcpy(buffer + COMPLETION_COUNTER_SIZE, text, strlen(text));

			g_output_stream_write(out_stream, buffer, block_size, NULL, &err);
		}

		g_debug("Closing file");
		g_io_stream_close(G_IO_STREAM(file_stream), NULL, NULL);
		g_object_unref(file_stream);
	}
	else
	{
		g_warning("Couldn't open file (rw): \"%s\"", path);
	}

	if(err)
	{
		g_warning("%s", err->message);
		g_error_free(err);
	}

	g_free(path);
}
static void
handle_channels_cb (TpSimpleHandler *handler,
  TpAccount *account,
  TpConnection *connection,
  GList *channels,
  GList *request_satisfied,
  gint64 user_aciton_time,
  TpHandleChannelsContext *handler_context,
  gpointer user_data)
{
  TpChannel *channel = channels->data;
  gchar *path = g_build_filename (
    g_get_user_config_dir (),
    "phoenix",
    "auth",
    NULL);
  GFile *file = g_file_new_for_path (path);
  GFileIOStream *stream;
  GDataInputStream *input = NULL;
  char *password = NULL;
  char *line;

  if (g_list_length (channels) != 1)
    {
      GError err = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
        "Can only handle one channel at a time" };
      tp_handle_channels_context_fail (handler_context,
        &err);
      goto out;
    }

  stream = g_file_open_readwrite (file, NULL, NULL);

  if (stream == NULL)
    {
      GError err = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
        "No authenication data stored" };
      tp_handle_channels_context_fail (handler_context,
        &err);
      goto out;
    }

  input = g_data_input_stream_new (
    g_io_stream_get_input_stream (G_IO_STREAM (stream)));
  while ((line = g_data_input_stream_read_line_utf8 (input, NULL, NULL, NULL))
      != NULL)
    {
      gchar **r = g_strsplit (line, " ", 2);
      if (r[0] == NULL || r[1] == NULL)
        continue;

      if (!tp_strdiff (r[0], tp_account_get_path_suffix (account)))
        {
          password = g_strdup (r[1]);
          printf ("Found password: %s\n", password);
          g_strfreev(r);
          break;
        }
      g_strfreev(r);
    }
  g_object_unref (input);

  if (password == NULL)
    {
      GError err = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
        "No authenication data stored for this account" };
      tp_handle_channels_context_fail (handler_context,
        &err);
      goto out;
    }

  tp_handle_channels_context_accept (handler_context);

  tp_cli_channel_interface_sasl_authentication_connect_to_sasl_status_changed
    (channel, sasl_status_changed_cb, NULL, NULL, NULL, NULL);
  provide_password (channel, password);

out:
  g_free (path);
  g_free (password);
}