Changeset a338faa


Ignore:
Timestamp:
2012-06-04T13:55:58Z (8 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
00f1e93
Parents:
0153ba9
Message:

Use xmltree to save user settings, in preparation for allowing other storage
media than local fs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • storage_xml.c

    r0153ba9 ra338faa  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2006 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2929#include "arc.h"
    3030#include "md5.h"
     31#include "xmltree.h"
    3132
    3233#include <glib/gstdio.h>
     
    4142
    4243/* To make it easier later when extending the format: */
    43 #define XML_FORMAT_VERSION 1
     44#define XML_FORMAT_VERSION "1"
    4445
    4546struct xml_parsedata
     
    422423}
    423424
    424 static int xml_printf( int fd, int indent, char *fmt, ... )
    425 {
    426         va_list params;
    427         char *out;
    428         char tabs[9] = "\t\t\t\t\t\t\t\t";
    429         int len;
    430        
    431         /* Maybe not very clean, but who needs more than 8 levels of indentation anyway? */
    432         if( write( fd, tabs, indent <= 8 ? indent : 8 ) != indent )
    433                 return 0;
    434        
    435         va_start( params, fmt );
    436         out = g_markup_vprintf_escaped( fmt, params );
    437         va_end( params );
    438        
    439         len = strlen( out );
    440         len -= write( fd, out, len );
    441         g_free( out );
    442        
    443         return len == 0;
    444 }
    445 
    446425static gboolean xml_save_nick( gpointer key, gpointer value, gpointer data );
    447426
    448 static storage_status_t xml_save( irc_t *irc, int overwrite )
    449 {
    450         char path[512], *path2, *pass_buf = NULL;
     427struct xt_node *xml_generate( irc_t *irc )
     428{
     429        char *pass_buf = NULL;
    451430        set_t *set;
    452431        account_t *acc;
    453         int fd;
    454432        md5_byte_t pass_md5[21];
    455433        md5_state_t md5_state;
    456434        GSList *l;
    457        
    458         path2 = g_strdup( irc->user->nick );
    459         nick_lc( path2 );
    460         g_snprintf( path, sizeof( path ) - 2, "%s%s%s", global.conf->configdir, path2, ".xml" );
    461         g_free( path2 );
    462        
    463         if( !overwrite && g_access( path, F_OK ) == 0 )
    464                 return STORAGE_ALREADY_EXISTS;
    465        
    466         strcat( path, ".XXXXXX" );
    467         if( ( fd = mkstemp( path ) ) < 0 )
    468         {
    469                 irc_rootmsg( irc, "Error while opening configuration file." );
    470                 return STORAGE_OTHER_ERROR;
    471         }
     435        struct xt_node *root, *cur;
    472436       
    473437        /* Generate a salted md5sum of the password. Use 5 bytes for the salt
     
    482446        pass_buf = base64_encode( pass_md5, 21 );
    483447       
    484         if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc->user->nick, pass_buf, XML_FORMAT_VERSION ) )
    485                 goto write_error;
     448        root = cur = xt_new_node( "user", NULL, NULL );
     449        xt_add_attr( cur, "nick", irc->user->nick );
     450        xt_add_attr( cur, "password", pass_buf );
     451        xt_add_attr( cur, "version", XML_FORMAT_VERSION );
    486452       
    487453        g_free( pass_buf );
     
    489455        for( set = irc->b->set; set; set = set->next )
    490456                if( set->value && !( set->flags & SET_NOSAVE ) )
    491                         if( !xml_printf( fd, 1, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
    492                                 goto write_error;
     457                {
     458                        struct xt_node *xset;
     459                        xt_add_child( cur, xset = xt_new_node( "setting", set->value, NULL ) );
     460                        xt_add_attr( xset, "name", set->key );
     461                }
    493462       
    494463        for( acc = irc->b->accounts; acc; acc = acc->next )
     
    502471                g_free( pass_cr );
    503472               
    504                 if( !xml_printf( fd, 1, "<account protocol=\"%s\" handle=\"%s\" password=\"%s\" "
    505                                         "autoconnect=\"%d\" tag=\"%s\"", acc->prpl->name, acc->user,
    506                                         pass_b64, acc->auto_connect, acc->tag ) )
    507                 {
    508                         g_free( pass_b64 );
    509                         goto write_error;
    510                 }
     473                cur = xt_new_node( "account", NULL, NULL );
     474                xt_add_attr( cur, "protocol", acc->prpl->name );
     475                xt_add_attr( cur, "handle", acc->user );
     476                xt_add_attr( cur, "password", pass_b64 );
     477                xt_add_attr( cur, "autoconnect", acc->auto_connect ? "true" : "false" );
     478                xt_add_attr( cur, "tag", acc->tag );
     479                if( acc->server && acc->server[0] )
     480                        xt_add_attr( cur, "server", acc->server );
     481               
    511482                g_free( pass_b64 );
    512                
    513                 if( acc->server && acc->server[0] && !xml_printf( fd, 0, " server=\"%s\"", acc->server ) )
    514                         goto write_error;
    515                 if( !xml_printf( fd, 0, ">\n" ) )
    516                         goto write_error;
    517483               
    518484                for( set = acc->set; set; set = set->next )
    519485                        if( set->value && !( set->flags & ACC_SET_NOSAVE ) )
    520                                 if( !xml_printf( fd, 2, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
    521                                         goto write_error;
     486                        {
     487                                struct xt_node *xset;
     488                                xt_add_child( cur, xset = xt_new_node( "setting", set->value, NULL ) );
     489                                xt_add_attr( xset, "name", set->key );
     490                        }
    522491               
    523492                /* This probably looks pretty strange. g_hash_table_foreach
     
    528497                   return TRUE on write errors. Which means, if we found
    529498                   something, there was an error. :-) */
    530                 if( g_hash_table_find( acc->nicks, xml_save_nick, & fd ) )
    531                         goto write_error;
    532                
    533                 if( !xml_printf( fd, 1, "</account>\n" ) )
    534                         goto write_error;
     499                g_hash_table_find( acc->nicks, xml_save_nick, cur );
     500               
     501                xt_add_child( root, cur );
    535502        }
    536503       
     
    542509                        continue;
    543510               
    544                 if( !xml_printf( fd, 1, "<channel name=\"%s\" type=\"%s\">\n",
    545                                  ic->name, set_getstr( &ic->set, "type" ) ) )
    546                         goto write_error;
     511                cur = xt_new_node( "channel", NULL, NULL );
     512                xt_add_attr( cur, "name", ic->name );
     513                xt_add_attr( cur, "type", set_getstr( &ic->set, "type" ) );
    547514               
    548515                for( set = ic->set; set; set = set->next )
    549516                        if( set->value && strcmp( set->key, "type" ) != 0 )
    550                                 if( !xml_printf( fd, 2, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
    551                                         goto write_error;
    552                
    553                 if( !xml_printf( fd, 1, "</channel>\n" ) )
    554                         goto write_error;
    555         }
    556        
    557         if( !xml_printf( fd, 0, "</user>\n" ) )
    558                 goto write_error;
     517                        {
     518                                struct xt_node *xset;
     519                                xt_add_child( cur, xset = xt_new_node( "setting", set->value, NULL ) );
     520                                xt_add_attr( xset, "name", set->key );
     521                        }
     522               
     523                xt_add_child( root, cur );
     524        }
     525       
     526        return root;
     527}
     528
     529static storage_status_t xml_save( irc_t *irc, int overwrite )
     530{
     531        char path[512], *path2, *xml;
     532        struct xt_node *tree;
     533        int fd;
     534       
     535        path2 = g_strdup( irc->user->nick );
     536        nick_lc( path2 );
     537        g_snprintf( path, sizeof( path ) - 2, "%s%s%s", global.conf->configdir, path2, ".xml" );
     538        g_free( path2 );
     539       
     540        if( !overwrite && g_access( path, F_OK ) == 0 )
     541                return STORAGE_ALREADY_EXISTS;
     542       
     543        strcat( path, ".XXXXXX" );
     544        if( ( fd = mkstemp( path ) ) < 0 )
     545        {
     546                irc_rootmsg( irc, "Error while opening configuration file." );
     547                return STORAGE_OTHER_ERROR;
     548        }
     549       
     550        tree = xml_generate( irc );
     551        xml = xt_to_string( tree );
     552        write( fd, xml, strlen( xml ) );
    559553       
    560554        fsync( fd );
     
    577571
    578572write_error:
    579         g_free( pass_buf );
    580573       
    581574        irc_rootmsg( irc, "Write error. Disk full?" );
     
    587580static gboolean xml_save_nick( gpointer key, gpointer value, gpointer data )
    588581{
    589         return !xml_printf( *( (int*) data ), 2, "<buddy handle=\"%s\" nick=\"%s\" />\n", key, value );
     582        struct xt_node *node = xt_new_node( "buddy", NULL, NULL );
     583        xt_add_attr( node, "handle", key );
     584        xt_add_attr( node, "nick", value );
     585        xt_add_child( (struct xt_node *) data, node );
     586       
     587        return FALSE;
    590588}
    591589
Note: See TracChangeset for help on using the changeset viewer.