Logo Search packages:      
Sourcecode: easytag version File versions  Download package

ogg_tag.c

/* ogg_tag.c - 2001/11/08 */
/*
 *  EasyTAG - Tag editor for MP3 and Ogg Vorbis files
 *  Copyright (C) 2001-2003  Jerome Couderc <easytag@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <config.h> // For definition of ENABLE_OGG

#ifdef ENABLE_OGG

#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>
#include <unistd.h>

#include "easytag.h"
#include "ogg_tag.h"
#include "vcedit.h"
#include "et_core.h"
#include "misc.h"
#include "setting.h"
#include "charset.h"

#ifdef WIN32
// for mkstemp
#   include "win32dep.h"
#endif


/***************
 * Declaration *
 ***************/

#define MULTIFIELD_SEPARATOR " - "

/* Ogg Vorbis fields names in UTF-8 : http://www.xiph.org/vorbis/doc/v-comment.html
 *
 * ALBUM       : if appropriate, an album name
 * ARTIST      : for information to be displayed on systems with limited display capabilities. it is not a replacement for the ENSEMBLE and PERFORMER tags, but typically will summarize them.
 * PUBLISHER   : who publishes the disc the track came from
 * COPYRIGHT   : who holds copyright to the track or disc the track is on
 * DISCNUMBER  : if part of a multi-disc album, put the disc number here
 * ISRC        : this number lets you order a CD over the phone from a record shop.
 * EAN/UPN     : there may be a barcode on the CD; it is most likely an EAN or UPN (Universal Product Number).
 * LABEL       : the record label or imprint on the disc
 * LABELNO     : record labels often put the catalog number of the source media somewhere on the packaging. use this tag to record it.
 * LICENSE     : the license, or URL for the license the track is under. for instance, the Open Audio license.
 * OPUS        : the number of the work; eg, Opus 10, BVW 81, K6
 * SOURCEMEDIA : the recording media the track came from. eg, CD, Cassette, Radio Broadcast, LP, CD Single
 * TITLE       : "the work", whether a symphony, or a pop song
 * TRACKNUMBER : the track number on the CD
 * TRACKTOTAL  : 
 * VERSION     : Make sure you don't put DATE or LOCATION information in this tag. "live", "acoustic", "Radio Edit" "12 inch remix" might be typical values of this tag
 * ENCODED-BY  : The person who encoded the Ogg file. May include contact information such as email address and phone number.
 * ENCODING    : Put the settings you used to encode the Ogg file here. This tag is NOT expected to be stored or returned by cddb type databases. It includes information about the quality setting, bit rate, and bitrate management settings used to encode the Ogg. It also is used for information about which encoding software was used to do the encoding.
 * 
 * The remaining tags are multiples; if they are present more than once, all their occurances are considered significant.
 * 
 * COMPOSER    : composer of the work. eg, Gustav Mahler
 * ARRANGER    : the person who arranged the piece, eg, Ravel
 * LYRICIST    : the person who wrote the lyrics, eg Donizetti
 * AUTHOR      : for text that is spoken, or was originally meant to be spoken, the author, eg JRR Tolkien
 * CONDUCTOR   : conductor of the work; eg Herbert von Karajan. choir directors would also use this tag.
 * PERFORMER   : individual performers singled out for mention; eg, Yoyo Ma (violinist)
 * ENSEMBLE    : the group playing the piece, whether orchestra, singing duo, or rock and roll band.
 * PART        : a division within a work; eg, a movement of a symphony. Some tracks contain several parts. Use a single PART tag for each part contained in a track. ie, PART="Oh sole mio"
 * PARTNUMBER  : The part number goes in here. You can use any format you like, such as Roman numerals, regular numbers, or whatever. The numbers should be entered in such a way that an alphabetical sort on this tag will correctly show the proper ordering of all the oggs that contain the contain the piece of music.
 * GENRE       : like the genre tag from the cddb but without the limitations. You can put any genre you want in this tag. If you think "Pink Floyd" are a genre unto themselves, say so here. For crossover works, or ambiguous works, use as many GENRE tags as you think it takes to describe the styles used.
 * DATE        : date or date-time of relevance to the track. The date must be in ISO 8601 format, but may be followed by a space character, then any text you wish, including the same date in any other format. None of the alternate formats in ISO 8601 may be used. Only the primary format in ISO 8601 is to be used. q.v. http://www.cl.cam.ac.uk/~mgk25/iso-time.html eg, DATE="1999-08-16 (recorded)" or DATE="1999-08-16 recorded August 16, 1999"
 * LOCATION    : location of recording, or other location of interest
 * COMMENT     : additional comments of any nature.
 */



/**************
 * Prototypes *
 **************/
gboolean Ogg_Tag_Write_File (FILE *file_in, gchar *filename_in, vcedit_state *state);


/*************
 * Functions *
 *************/

/*
 * Read tag data into an Ogg Vorbis file.
 * Note:
 *  - if field is found but contains no info (strlen(str)==0), we don't read it
 */
gboolean Ogg_Tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
{
    FILE           *file;
    vcedit_state   *state;
    vorbis_comment *vc;
    gchar          *string = NULL;
    gchar          *string1 = NULL;
    gchar          *filename_utf8 = filename_to_display(filename);
    guint           field_num, i;


    if (!filename || !FileTag)
        return FALSE;

    ogg_error_msg = NULL;

    if ( (file=fopen(filename,"rb")) == NULL )
    {
        g_print(_("ERROR while opening file: '%s' (%s).\n\a"),filename_utf8,g_strerror(errno));
        g_free(filename_utf8);
        return FALSE;
    }

    {
    // Skip the id3v2 tag
    guchar tmp_id3[4];
    gulong id3v2size;

    // Check if there is an ID3v2 tag...
    fseek(file, 0L, SEEK_SET);
    if (fread(tmp_id3, 1, 4, file) == 4)
    {
        // Calculate ID3v2 length
        if (tmp_id3[0] == 'I' && tmp_id3[1] == 'D' && tmp_id3[2] == '3' && tmp_id3[3] < 0xFF)
        {
            // id3v2 tag skipeer $49 44 33 yy yy xx zz zz zz zz [zz size]
            fseek(file, 2, SEEK_CUR); // Size is 6-9 position
            if (fread(tmp_id3, 1, 4, file) == 4)
            {
                id3v2size = 10 + ( (long)(tmp_id3[3])        | ((long)(tmp_id3[2]) << 7)
                                | ((long)(tmp_id3[1]) << 14) | ((long)(tmp_id3[0]) << 21) );
                fseek(file, id3v2size, SEEK_SET);
                g_print(_("Warning : The Ogg Vorbis file '%s' contains an ID3v2 tag.\n"),filename_utf8);
            }else
            {
                fseek(file, 0L, SEEK_SET);
            }
        }else
        {
            fseek(file, 0L, SEEK_SET);
        }
    }else
    {
        fseek(file, 0L, SEEK_SET);
    }
    }
    
    state = vcedit_new_state();    // Allocate memory for 'state'
    if ( vcedit_open(state,file) < 0 )
    {
        g_print(_("ERROR: Failed to open file: '%s' as vorbis (%s).\n"),filename_utf8,vcedit_error(state));
        ogg_error_msg = vcedit_error(state);
        fclose(file);
        g_free(filename_utf8);
        return FALSE;
    }


    /* Get data from tag */
    vc = vcedit_comments(state);
    //{gint i; for (i=0;i<vc->comments;i++) g_print("%s -> Ogg vc:'%s'\n",g_path_get_basename(filename),vc->user_comments[i]);}

    /*********
     * Title *
     *********/
    /* Note : don't forget to add any new field to 'Save unsupported fields' */
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"TITLE",field_num++)) != NULL )
    {
        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->title==NULL)
                FileTag->title = g_strdup(string);
            else
                FileTag->title = g_strconcat(FileTag->title,MULTIFIELD_SEPARATOR,string,NULL);
            // If strlen = 0, then no allocated data!
        }
    }

    /**********
     * Artist *
     **********/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ARTIST",field_num++)) != NULL )
    {
        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->artist==NULL)
                FileTag->artist = g_strdup(string);
            else
                FileTag->artist = g_strconcat(FileTag->artist,MULTIFIELD_SEPARATOR,string,NULL);
        }
    }

    /*********
     * Album *
     *********/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ALBUM",field_num++)) != NULL )
    {
        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->album==NULL)
                FileTag->album = g_strdup(string);
            else
                FileTag->album = g_strconcat(FileTag->album,MULTIFIELD_SEPARATOR,string,NULL);
        }
    }

    /*******************************
     * Disc Number (Part of a Set) *
     *******************************/
    if ( (string = vorbis_comment_query(vc,"DISCNUMBER",0)) != NULL && g_utf8_strlen(string, -1) > 0 )
        FileTag->disc_number = g_strdup(string);

    /********
     * Year *
     ********/
    if ( (string = vorbis_comment_query(vc,"DATE",0)) != NULL && g_utf8_strlen(string, -1) > 0 )
        FileTag->year = g_strdup(string);

    /*************************
     * Track and Total Track *
     *************************/
    if ( (string = vorbis_comment_query(vc,"TRACKNUMBER",0)) != NULL && g_utf8_strlen(string, -1) > 0 )
    {
        if (NUMBER_TRACK_FORMATED)
        {
            // Ckeck if TRACKTOTAL used, else takes it in TRACKNUMBER
            if ( (string1 = vorbis_comment_query(vc,"TRACKTOTAL",0)) != NULL && g_utf8_strlen(string1, -1) > 0 )
            {
                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string1));
            }else
            if ( (string1 = g_utf8_strchr(string, -1, '/')) )
            {
                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string1+1));
                *string1 = '\0';
            }
            FileTag->track = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string));
        }else
        {
            // Ckeck if TRACKTOTAL used, else takes it in TRACKNUMBER
            if ( (string1 = vorbis_comment_query(vc,"TRACKTOTAL",0)) != NULL && g_utf8_strlen(string1, -1) > 0 )
            {
                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string1));
            }else
            if ( (string1 = g_utf8_strchr(string, -1, '/')) )
            {
                FileTag->track_total = g_strdup(string1+1);
                *string1 = '\0';
            }
            FileTag->track = g_strdup(string);
        }
    }

    /*********
     * Genre *
     *********/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"GENRE",field_num++)) != NULL )
    {
        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->genre==NULL)
                FileTag->genre = g_strdup(string);
            else
                FileTag->genre = g_strconcat(FileTag->genre,MULTIFIELD_SEPARATOR,string,NULL);
        }
    }

    /***********
     * Comment *
     ***********/
    field_num = 0;
    string1 = NULL; // Cause it may be not updated into the 'while' condition
    while ( ((string  = vorbis_comment_query(vc,"COMMENT",field_num)) != NULL )   // Winamp format
         || ((string1 = vorbis_comment_query(vc,"",       field_num)) != NULL ) ) // Xmms format
    {
        if ( string && g_utf8_strlen(string, -1) > 0 ) // Contains comment to Winamp format and we prefer this format (field name defined)
        {
            if (FileTag->comment==NULL)
                FileTag->comment = g_strdup(string);
            else
                FileTag->comment = g_strconcat(FileTag->comment,MULTIFIELD_SEPARATOR,string,NULL);
            if (string1 && g_utf8_strlen(string1, -1) > 0)
                g_free(string1);
        }else if ( string1 && g_utf8_strlen(string1, -1) > 0 ) // Contains comment to Xmms format only
        {
            if (FileTag->comment==NULL)
                FileTag->comment = g_strdup(string1);
            else
                FileTag->comment = g_strconcat(FileTag->comment,MULTIFIELD_SEPARATOR,string1,NULL);
        }
        string1 = NULL;
        field_num++;
    }

    /************
     * Composer *
     ************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"COMPOSER",field_num++)) != NULL )
    {
        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->composer==NULL)
                FileTag->composer = g_strdup(string);
            else
                FileTag->composer = g_strconcat(FileTag->composer,MULTIFIELD_SEPARATOR,string,NULL);
        }
    }

    /*******************
     * Original artist *
     *******************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"PERFORMER",field_num++)) != NULL )
    {
        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->orig_artist==NULL)
                FileTag->orig_artist = g_strdup(string);
            else
                FileTag->orig_artist = g_strconcat(FileTag->orig_artist,MULTIFIELD_SEPARATOR,string,NULL);
        }
    }

    /*************
     * Copyright *
     *************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"COPYRIGHT",field_num++)) != NULL )
    {
        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->copyright==NULL)
                FileTag->copyright = g_strdup(string);
            else
                FileTag->copyright = g_strconcat(FileTag->copyright,MULTIFIELD_SEPARATOR,string,NULL);
        }
    }

    /*******
     * URL *
     *******/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"LICENSE",field_num++)) != NULL )
    {
        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->url==NULL)
                FileTag->url = g_strdup(string);
            else
                FileTag->url = g_strconcat(FileTag->url,MULTIFIELD_SEPARATOR,string,NULL);
        }
    }

    /**************
     * Encoded by *
     **************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ENCODED-BY",field_num++)) != NULL )
    {
        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->encoded_by==NULL)
                FileTag->encoded_by = g_strdup(string);
            else
                FileTag->encoded_by = g_strconcat(FileTag->encoded_by,MULTIFIELD_SEPARATOR,string,NULL);
        }
    }


    /***************************
     * Save unsupported fields *
     ***************************/
    for (i=0;i<(guint)vc->comments;i++)
    {
        if ( strncasecmp(vc->user_comments[i],"TITLE=",       6) != 0
          && strncasecmp(vc->user_comments[i],"ARTIST=",      7) != 0
          && strncasecmp(vc->user_comments[i],"ALBUM=",       6) != 0
          && strncasecmp(vc->user_comments[i],"DISCNUMBER=", 11) != 0
          && strncasecmp(vc->user_comments[i],"DATE=",        5) != 0
          && strncasecmp(vc->user_comments[i],"TRACKNUMBER=",12) != 0
          && strncasecmp(vc->user_comments[i],"TRACKTOTAL=", 11) != 0
          && strncasecmp(vc->user_comments[i],"GENRE=",       6) != 0
          && strncasecmp(vc->user_comments[i],"COMMENT=",     8) != 0
          && strncasecmp(vc->user_comments[i],"=",            1) != 0
          && strncasecmp(vc->user_comments[i],"COMPOSER=",    9) != 0
          && strncasecmp(vc->user_comments[i],"PERFORMER=",  10) != 0
          && strncasecmp(vc->user_comments[i],"COPYRIGHT=",  10) != 0
          && strncasecmp(vc->user_comments[i],"LICENSE=",     8) != 0
          && strncasecmp(vc->user_comments[i],"ENCODED-BY=", 11) != 0 )
        {
            FileTag->other = g_list_append(FileTag->other,g_strdup(vc->user_comments[i]));
        }
    }

    vcedit_clear(state);
    fclose(file);
    g_free(filename_utf8);

    return TRUE;
}



gboolean Ogg_Tag_Write_File_Tag (ET_File *ETFile)
{
    File_Tag       *FileTag;
    gchar          *filename;
    gchar          *filename_utf8;
    gchar          *basename_utf8;
    FILE           *file_in;
    vcedit_state   *state;
    vorbis_comment *vc;
    gchar          *string;
    GList          *list;

    if (!ETFile || !ETFile->FileTag)
        return FALSE;

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

    /* Test to know if we can write into the file */
    if ( (file_in=fopen(filename,"rb"))==NULL )
    {
        g_print(_("ERROR while opening file: '%s' (%s).\n\a"),filename_utf8,g_strerror(errno));
        g_free(filename_utf8);
        return FALSE;
    }

    {
    // Skip the id3v2 tag
    guchar tmp_id3[4];
    gulong id3v2size;

    // Check if there is an ID3v2 tag...
    fseek(file_in, 0L, SEEK_SET);
    if (fread(tmp_id3, 1, 4, file_in) == 4)
    {
        // Calculate ID3v2 length
        if (tmp_id3[0] == 'I' && tmp_id3[1] == 'D' && tmp_id3[2] == '3' && tmp_id3[3] < 0xFF)
        {
            // id3v2 tag skipeer $49 44 33 yy yy xx zz zz zz zz [zz size]
            fseek(file_in, 2, SEEK_CUR); // Size is 6-9 position
            if (fread(tmp_id3, 1, 4, file_in) == 4)
            {
                id3v2size = 10 + ( (long)(tmp_id3[3])        | ((long)(tmp_id3[2]) << 7)
                                | ((long)(tmp_id3[1]) << 14) | ((long)(tmp_id3[0]) << 21) );
                fseek(file_in, id3v2size, SEEK_SET);
            }else
            {
                fseek(file_in, 0L, SEEK_SET);
            }
        }else
        {
            fseek(file_in, 0L, SEEK_SET);
        }
    }else
    {
        fseek(file_in, 0L, SEEK_SET);
    }
    }

    state = vcedit_new_state();    // Allocate memory for 'state'
    if ( vcedit_open(state,file_in) < 0 )
    {
        g_print(_("ERROR: Failed to open file: '%s' as vorbis (%s).\n"),filename_utf8,vcedit_error(state));
        ogg_error_msg = vcedit_error(state);
        fclose(file_in);
        g_free(filename_utf8);
        return FALSE;
    }

    /* Get data from tag */
    vc = vcedit_comments(state);
    vorbis_comment_clear(vc);
    vorbis_comment_init(vc);

    /*********
     * Title *
     *********/
    if ( FileTag->title )
    {
        string = g_strconcat("TITLE=",FileTag->title,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /**********
     * Artist *
     **********/
    if ( FileTag->artist )
    {
        string = g_strconcat("ARTIST=",FileTag->artist,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /*********
     * Album *
     *********/
    if ( FileTag->album )
    {
        string = g_strconcat("ALBUM=",FileTag->album,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /***************
     * Disc Number *
     ***************/
    if ( FileTag->disc_number )
    {
        string = g_strconcat("DISCNUMBER=",FileTag->disc_number,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /********
     * Year *
     ********/
    if ( FileTag->year )
    {
        string = g_strconcat("DATE=",FileTag->year,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /*************************
     * Track and Total Track *
     *************************/
    if ( FileTag->track )
    {
        string = g_strconcat("TRACKNUMBER=",FileTag->track,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }
    if ( FileTag->track_total /*&& strlen(FileTag->track_total)>0*/ )
    {
        string = g_strconcat("TRACKTOTAL=",FileTag->track_total,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /*********
     * Genre *
     *********/
    if ( FileTag->genre )
    {
        string = g_strconcat("GENRE=",FileTag->genre,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /***********
     * Comment *
     ***********/
    // We write the comment using the "both" format
    if ( FileTag->comment )
    {
        // Format used in winamp plugin
        string = g_strconcat("COMMENT=",FileTag->comment,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);

        if (OGG_TAG_WRITE_XMMS_COMMENT)
        {
            // Format used into xmms-1.2.5
            string  = g_strconcat("=",FileTag->comment,NULL);
            vorbis_comment_add(vc,string);
            g_free(string);
        }
    }

    /************
     * Composer *
     ************/
    if ( FileTag->composer )
    {
        string = g_strconcat("COMPOSER=",FileTag->composer,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /*******************
     * Original artist *
     *******************/
    if ( FileTag->orig_artist )
    {
        string = g_strconcat("PERFORMER=",FileTag->orig_artist,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /*************
     * Copyright *
     *************/
    if ( FileTag->copyright )
    {
        string = g_strconcat("COPYRIGHT=",FileTag->copyright,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /*******
     * URL *
     *******/
    if ( FileTag->url )
    {
        string = g_strconcat("LICENSE=",FileTag->url,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }

    /**************
     * Encoded by *
     **************/
    if ( FileTag->encoded_by )
    {
        string = g_strconcat("ENCODED-BY=",FileTag->encoded_by,NULL);
        vorbis_comment_add(vc,string);
        g_free(string);
    }


    /**************************
     * Set unsupported fields *
     **************************/
    list = FileTag->other;
    while (list)
    {
        if (list->data)
            vorbis_comment_add(vc,(gchar *)list->data);
        list = list->next;
    }


    /* Write tag */
    if ( Ogg_Tag_Write_File(file_in,filename,state) == FALSE )
    {
        g_print(_("ERROR: Failed to write comments to file '%s' (%s).\n"),filename_utf8,vcedit_error(state));
        ogg_error_msg = vcedit_error(state);
        g_free(filename_utf8);
        return FALSE;
    }else
    {
        basename_utf8 = g_path_get_basename(filename_utf8);
        g_print(_("Written tag of '%s'\n"),basename_utf8);
        g_free(basename_utf8);
    }

    vcedit_clear(state);
    g_free(filename_utf8);

    return TRUE;
}



/* This function is based on work of :
 *  XMMS - Cross-platform multimedia player
 *  Copyright (C) 1998-2001  Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
 *  Copyright (C) 1999-2001  Håvard Kvålen
 *  Copyright (C) 2001, Jorn Baayen <jorn@nl.linux.org>
 */
gboolean Ogg_Tag_Write_File (FILE *file_in, gchar *filename_in, vcedit_state *state)
{
    gchar *filename_tmp;
    gint   file_mkstemp;
    FILE  *file_out;
    gboolean return_code = TRUE;

    filename_tmp = g_strdup_printf("%s.XXXXXX",filename_in);

    if ((file_mkstemp = mkstemp(filename_tmp)) < 0)
    {
        g_free(filename_tmp);
        fclose(file_in);
        return FALSE;
    }

    if ( (file_out=fdopen(file_mkstemp,"wb")) == NULL )
    {
        close(file_mkstemp);
        remove(filename_tmp);
        g_free(filename_tmp);

        fclose(file_in);
        return FALSE;
    }

    if (vcedit_write(state,file_out) < 0)
        return_code = FALSE;

    fclose(file_in);

    if (fclose(file_out) != 0)
        return_code = FALSE;

    if ( (return_code==FALSE) || (rename(filename_tmp,filename_in)<0) )
    {
        remove(filename_tmp);
        return_code = FALSE;
    }

    g_free(filename_tmp);

    return return_code;
}


#endif /* ENABLE_OGG */

Generated by  Doxygen 1.6.0   Back to index