Changeset 5b52a48


Ignore:
Timestamp:
2006-07-03T21:22:45Z (18 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
7e3592e
Parents:
911f2eb
Message:

Implemented per-account nick lists instead of per-protocol nick lists.
nick_t is dead, instead nicks are just saves in a per-account_t GLib
hash table. While doing this, the import_buddies command finally died
and text_save() disappeared, because the old file format can't handle
most of the new features in this branch anyway.

Still have to implement support for the new nick lists in text_load()!

Files:
18 edited

Legend:

Unmodified
Added
Removed
  • account.c

    r911f2eb r5b52a48  
    5858        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
    5959        set_setstr( &a->set, "username", user );
     60       
     61        a->nicks = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free );
    6062       
    6163        /* This function adds some more settings (and might want to do more
     
    126128                        for( a = irc->accounts; a; a = a->next )
    127129                                if( a->prpl == proto &&
    128                                     a->prpl->cmp_buddynames( handle, a->user ) == 0 )
     130                                    a->prpl->handle_cmp( handle, a->user ) == 0 )
    129131                                        ret = a;
    130132                }
     
    190192                                set_del( &a->set, a->set->key );
    191193                       
     194                        g_hash_table_destroy( a->nicks );
     195                       
    192196                        g_free( a->user );
    193197                        g_free( a->pass );
  • account.h

    r911f2eb r5b52a48  
    3838       
    3939        set_t *set;
     40        GHashTable *nicks;
    4041       
    4142        struct irc *irc;
  • bitlbee.h

    r911f2eb r5b52a48  
    124124#include "commands.h"
    125125#include "account.h"
     126#include "nick.h"
    126127#include "conf.h"
    127128#include "log.h"
  • irc.c

    r911f2eb r5b52a48  
    204204void irc_free(irc_t * irc)
    205205{
    206         account_t *account, *accounttmp;
     206        account_t *account;
    207207        user_t *user, *usertmp;
    208         nick_t *nick, *nicktmp;
    209208        help_t *helpnode, *helpnodetmp;
    210         set_t *setnode, *setnodetmp;
    211209       
    212210        log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );
     
    252250                query_del(irc, irc->queries);
    253251       
    254         if (irc->accounts != NULL) {
    255                 account = irc->accounts;
    256                 while (account != NULL) {
    257                         g_free(account->user);
    258                         g_free(account->pass);
    259                         g_free(account->server);
    260                         accounttmp = account;
    261                         account = account->next;
    262                         g_free(accounttmp);
    263                 }
    264         }
     252        while (irc->accounts)
     253                account_del(irc, irc->accounts);
     254       
     255        while (irc->set)
     256                set_del(&irc->set, irc->set->key);
    265257       
    266258        if (irc->users != NULL) {
     
    287279        g_hash_table_destroy(irc->watches);
    288280       
    289         if (irc->nicks != NULL) {
    290                 nick = irc->nicks;
    291                 while (nick != NULL) {
    292                         g_free(nick->nick);
    293                         g_free(nick->handle);
    294                                        
    295                         nicktmp = nick;
    296                         nick = nick->next;
    297                         g_free(nicktmp);
    298                 }
    299         }
    300281        if (irc->help != NULL) {
    301282                helpnode = irc->help;
     
    306287                        helpnode = helpnode->next;
    307288                        g_free(helpnodetmp);
    308                 }
    309         }
    310         if (irc->set != NULL) {
    311                 setnode = irc->set;
    312                 while (setnode != NULL) {
    313                         g_free(setnode->key);
    314                         g_free(setnode->def);
    315                         g_free(setnode->value);
    316                        
    317                         setnodetmp = setnode;
    318                         setnode = setnode->next;
    319                         g_free(setnodetmp);
    320289                }
    321290        }
  • irc.h

    r911f2eb r5b52a48  
    9898
    9999#include "user.h"
    100 #include "nick.h"
     100// #include "nick.h"
    101101
    102102extern GSList *irc_connection_list;
  • irc_commands.c

    r911f2eb r5b52a48  
    478478                if( u->gc )
    479479                        irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->acc->user,
    480                                    *u->gc->acc->server ? u->gc->acc->server : "", u->gc->acc->prpl->name );
     480                                   u->gc->acc->server && *u->gc->acc->server ? u->gc->acc->server : "",
     481                                   u->gc->acc->prpl->name );
    481482                else
    482483                        irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
  • nick.c

    r911f2eb r5b52a48  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2006 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2727#include "bitlbee.h"
    2828
    29 void nick_set( irc_t *irc, const char *handle, struct prpl *proto, const char *nick )
    30 {
    31         nick_t *m = NULL, *n = irc->nicks;
    32        
    33         while( n )
    34         {
    35                 if( ( g_strcasecmp( n->handle, handle ) == 0 ) && n->proto == proto )
    36                 {
    37                         g_free( n->nick );
    38                         n->nick = nick_dup( nick );
    39                         nick_strip( n->nick );
    40                        
    41                         return;
    42                 }
    43                 n = ( m = n )->next;    // :-P
    44         }
    45        
    46         if( m )
    47                 n = m->next = g_new0( nick_t, 1 );
     29/* Store handles in lower case and strip spaces, because AIM is braindead. */
     30static char *clean_handle( const char *orig )
     31{
     32        char *new = g_malloc( strlen( orig ) + 1 );
     33        int i = 0;
     34       
     35        do {
     36                if (*orig != ' ')
     37                        new[i++] = tolower( *orig );
     38        }
     39        while (*(orig++));
     40       
     41        return new;
     42}
     43
     44void nick_set( account_t *acc, const char *handle, const char *nick )
     45{
     46        char *store_handle, *store_nick = g_malloc( MAX_NICK_LENGTH + 1 );
     47       
     48        store_handle = clean_handle( handle );
     49        strncpy( store_nick, nick, MAX_NICK_LENGTH );
     50        nick_strip( store_nick );
     51       
     52        g_hash_table_replace( acc->nicks, store_handle, store_nick );
     53}
     54
     55char *nick_get( account_t *acc, const char *handle, const char *realname )
     56{
     57        static char nick[MAX_NICK_LENGTH+1];
     58        char *store_handle, *found_nick;
     59        int inf_protection = 256;
     60       
     61        memset( nick, 0, MAX_NICK_LENGTH + 1 );
     62       
     63        store_handle = clean_handle( handle );
     64        /* Find out if we stored a nick for this person already. If not, try
     65           to generate a sane nick automatically. */
     66        if( ( found_nick = g_hash_table_lookup( acc->nicks, store_handle ) ) )
     67        {
     68                strncpy( nick, found_nick, MAX_NICK_LENGTH );
     69        }
    4870        else
    49                 n = irc->nicks = g_new0( nick_t, 1 );
    50        
    51         n->handle = g_strdup( handle );
    52         n->proto = proto;
    53         n->nick = nick_dup( nick );
    54        
    55         nick_strip( n->nick );
    56 }
    57 
    58 char *nick_get( irc_t *irc, const char *handle, struct prpl *proto, const char *realname )
    59 {
    60         static char nick[MAX_NICK_LENGTH+1];
    61         nick_t *n = irc->nicks;
    62         int inf_protection = 256;
    63        
    64         memset( nick, 0, MAX_NICK_LENGTH + 1 );
    65        
    66         while( n && !*nick )
    67                 if( ( n->proto == proto ) && ( g_strcasecmp( n->handle, handle ) == 0 ) )
    68                         strcpy( nick, n->nick );
    69                 else
    70                         n = n->next;
    71        
    72         if( !n )
    7371        {
    7472                char *s;
     
    8684               
    8785                nick_strip( nick );
    88                 if( set_getint( &irc->set, "lcnicks" ) )
     86                if( set_getbool( &acc->irc->set, "lcnicks" ) )
    8987                        nick_lc( nick );
    9088        }
    91        
    92         while( !nick_ok( nick ) || user_find( irc, nick ) )
     89        g_free( store_handle );
     90       
     91        /* Now, find out if the nick is already in use at the moment, and make
     92           subtle changes to make it unique. */
     93        while( !nick_ok( nick ) || user_find( acc->irc, nick ) )
    9394        {
    9495                if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) )
     
    106107                        int i;
    107108                       
    108                         irc_usermsg( irc, "WARNING: Almost had an infinite loop in nick_get()! "
    109                                           "This used to be a fatal BitlBee bug, but we tried to fix it. "
    110                                           "This message should *never* appear anymore. "
    111                                           "If it does, please *do* send us a bug report! "
    112                                           "Please send all the following lines in your report:" );
    113                        
    114                         irc_usermsg( irc, "Trying to get a sane nick for handle %s", handle );
     109                        irc_usermsg( acc->irc, "WARNING: Almost had an infinite loop in nick_get()! "
     110                                               "This used to be a fatal BitlBee bug, but we tried to fix it. "
     111                                               "This message should *never* appear anymore. "
     112                                               "If it does, please *do* send us a bug report! "
     113                                               "Please send all the following lines in your report:" );
     114                       
     115                        irc_usermsg( acc->irc, "Trying to get a sane nick for handle %s", handle );
    115116                        for( i = 0; i < MAX_NICK_LENGTH; i ++ )
    116                                 irc_usermsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] );
    117                        
    118                         irc_usermsg( irc, "FAILED. Returning an insane nick now. Things might break. "
    119                                           "Good luck, and please don't forget to paste the lines up here "
    120                                           "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
     117                                irc_usermsg( acc->irc, "Char %d: %c/%d", i, nick[i], nick[i] );
     118                       
     119                        irc_usermsg( acc->irc, "FAILED. Returning an insane nick now. Things might break. "
     120                                               "Good luck, and please don't forget to paste the lines up here "
     121                                               "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
    121122                       
    122123                        g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() );
     
    126127        }
    127128       
    128         return( nick );
    129 }
    130 
    131 void nick_del( irc_t *irc, const char *nick )
    132 {
    133         nick_t *l = NULL, *n = irc->nicks;
    134        
    135         while( n )
    136         {
    137                 if( g_strcasecmp( n->nick, nick ) == 0 )
    138                 {
    139                         if( l )
    140                                 l->next = n->next;
    141                         else
    142                                 irc->nicks = n->next;
    143                        
    144                         g_free( n->handle );
    145                         g_free( n->nick );
    146                         g_free( n );
    147                        
    148                         break;
    149                 }
    150                 n = (l=n)->next;
    151         }
     129        return nick;
     130}
     131
     132void nick_del( account_t *acc, const char *handle )
     133{
     134        g_hash_table_remove( acc->nicks, handle );
    152135}
    153136
  • nick.h

    r911f2eb r5b52a48  
    2424*/
    2525
    26 typedef struct __NICK
    27 {
    28         char *handle;
    29         struct prpl *proto;
    30         char *nick;
    31         struct __NICK *next;
    32 } nick_t;
    33 
    34 void nick_set( irc_t *irc, const char *handle, struct prpl *proto, const char *nick );
    35 char *nick_get( irc_t *irc, const char *handle, struct prpl *proto, const char *realname );
    36 void nick_del( irc_t *irc, const char *nick );
     26void nick_set( account_t *acc, const char *handle, const char *nick );
     27char *nick_get( account_t *acc, const char *handle, const char *realname );
     28void nick_del( account_t *acc, const char *handle );
    3729void nick_strip( char *nick );
    3830
  • protocols/jabber/jabber.c

    r911f2eb r5b52a48  
    23802380        ret->alias_buddy = jabber_roster_update;
    23812381        ret->group_buddy = jabber_group_change;
    2382         ret->cmp_buddynames = g_strcasecmp;
     2382        ret->handle_cmp = g_strcasecmp;
    23832383
    23842384        register_protocol (ret);
  • protocols/msn/msn.c

    r911f2eb r5b52a48  
    432432        ret->rem_deny = msn_rem_deny;
    433433        ret->send_typing = msn_send_typing;
    434         ret->cmp_buddynames = g_strcasecmp;
     434        ret->handle_cmp = g_strcasecmp;
    435435
    436436        register_protocol(ret);
  • protocols/nogaim.c

    r911f2eb r5b52a48  
    366366       
    367367        memset( nick, 0, MAX_NICK_LENGTH + 1 );
    368         strcpy( nick, nick_get( gc->irc, handle, gc->acc->prpl, realname ) );
     368        strcpy( nick, nick_get( gc->acc, handle, realname ) );
    369369       
    370370        u = user_add( gc->irc, nick );
     
    378378                u->user = g_strndup( handle, s - handle );
    379379        }
    380         else if( *gc->acc->server )
     380        else if( gc->acc->server )
    381381        {
    382382                char *colon;
     
    778778       
    779779        /* It might be yourself! */
    780         if( b->gc->acc->prpl->cmp_buddynames( handle, b->gc->username ) == 0 )
     780        if( b->gc->acc->prpl->handle_cmp( handle, b->gc->username ) == 0 )
    781781        {
    782782                u = user_find( b->gc->irc, b->gc->irc->nick );
     
    10621062void bim_add_allow( struct gaim_connection *gc, char *handle )
    10631063{
    1064         if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->cmp_buddynames ) == NULL )
     1064        if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) == NULL )
    10651065        {
    10661066                gc->permit = g_slist_prepend( gc->permit, g_strdup( handle ) );
     
    10741074        GSList *l;
    10751075       
    1076         if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->cmp_buddynames ) ) )
     1076        if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) ) )
    10771077        {
    10781078                g_free( l->data );
     
    10851085void bim_add_block( struct gaim_connection *gc, char *handle )
    10861086{
    1087         if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->cmp_buddynames ) == NULL )
     1087        if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) == NULL )
    10881088        {
    10891089                gc->deny = g_slist_prepend( gc->deny, g_strdup( handle ) );
     
    10971097        GSList *l;
    10981098       
    1099         if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->cmp_buddynames ) ) )
     1099        if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) ) )
    11001100        {
    11011101                g_free( l->data );
  • protocols/nogaim.h

    r911f2eb r5b52a48  
    165165       
    166166        /* Mainly for AOL, since they think "Bung hole" == "Bu ngho le". *sigh* */
    167         int (* cmp_buddynames) (const char *who1, const char *who2);
     167        int (* handle_cmp) (const char *who1, const char *who2);
    168168};
    169169
  • protocols/oscar/oscar.c

    r911f2eb r5b52a48  
    26812681        ret->set_permit_deny = oscar_set_permit_deny;
    26822682        ret->keepalive = oscar_keepalive;
    2683         ret->cmp_buddynames = aim_sncmp;
    26842683        ret->get_status_string = oscar_get_status_string;
    26852684        ret->send_typing = oscar_send_typing;
     2685       
     2686        ret->handle_cmp = aim_sncmp;
    26862687
    26872688        register_protocol(ret);
  • protocols/yahoo/yahoo.c

    r911f2eb r5b52a48  
    409409        ret->chat_leave = byahoo_chat_leave;
    410410        ret->chat_open = byahoo_chat_open;
    411         ret->cmp_buddynames = g_strcasecmp;
     411
     412        ret->handle_cmp = g_strcasecmp;
    412413       
    413414        register_protocol(ret);
  • root_commands.c

    r911f2eb r5b52a48  
    466466                else
    467467                {
    468                         nick_set( irc, cmd[2], a->gc->acc->prpl, cmd[3] );
     468                        nick_set( a, cmd[2], cmd[3] );
    469469                }
    470470        }
     
    548548                else if( u->send_handler == buddy_send_handler )
    549549                {
    550                         nick_set( irc, u->handle, u->gc->acc->prpl, cmd[2] );
     550                        nick_set( u->gc->acc, u->handle, cmd[2] );
    551551                }
    552552               
     
    569569        u->gc->acc->prpl->remove_buddy( u->gc, u->handle, NULL );
    570570        user_del( irc, cmd[1] );
    571         nick_del( irc, cmd[1] );
     571        nick_del( u->gc->acc, u->handle );
    572572       
    573573        irc_usermsg( irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1] );
     
    879879                else
    880880                        irc_usermsg( irc, "%d, BitlBee: %s", num, q->question );
    881 }
    882 
    883 static void cmd_import_buddies( irc_t *irc, char **cmd )
    884 {
    885         struct gaim_connection *gc;
    886         account_t *a;
    887         nick_t *n;
    888        
    889         if( !( a = account_get( irc, cmd[1] ) ) )
    890         {
    891                 irc_usermsg( irc, "Invalid account" );
    892                 return;
    893         }
    894         else if( !( ( gc = a->gc ) && ( a->gc->flags & OPT_LOGGED_IN ) ) )
    895         {
    896                 irc_usermsg( irc, "That account is not on-line" );
    897                 return;
    898         }
    899        
    900         if( cmd[2] )
    901         {
    902                 if( g_strcasecmp( cmd[2], "clear" ) == 0 )
    903                 {
    904                         user_t *u;
    905                        
    906                         /* FIXME: Hmmm, this is actually pretty dangerous code... REMOVEME? :-) */
    907                         for( u = irc->users; u; u = u->next )
    908                                 if( u->gc == gc )
    909                                 {
    910                                         u->gc->acc->prpl->remove_buddy( u->gc, u->handle, NULL );
    911                                         user_del( irc, u->nick );
    912                                 }
    913                        
    914                         irc_usermsg( irc, "Old buddy list cleared." );
    915                 }
    916                 else
    917                 {
    918                         irc_usermsg( irc, "Invalid argument: %s", cmd[2] );
    919                         return;
    920                 }
    921         }
    922        
    923         for( n = gc->irc->nicks; n; n = n->next )
    924         {
    925                 if( n->proto == gc->acc->prpl && !user_findhandle( gc, n->handle ) )
    926                 {
    927                         gc->acc->prpl->add_buddy( gc, n->handle );
    928                         add_buddy( gc, NULL, n->handle, NULL );
    929                 }
    930         }
    931        
    932         irc_usermsg( irc, "Sent all add requests. Please wait for a while, the server needs some time to handle all the adds." );
    933881}
    934882
     
    951899        { "blist",          0, cmd_blist,          0 },
    952900        { "nick",           1, cmd_nick,           0 },
    953         { "import_buddies", 1, cmd_import_buddies, 0 },
    954901        { "qlist",          0, cmd_qlist,          0 },
    955902        { NULL }
  • storage_text.c

    r911f2eb r5b52a48  
    113113
    114114                http_decode( s );
    115                 nick_set( irc, s, prpl, nick );
     115                // FIXME!!!! nick_set( irc, s, prpl, nick );
    116116        }
    117117        fclose( fp );
    118        
    119         return STORAGE_OK;
    120 }
    121 
    122 static storage_status_t text_save( irc_t *irc, int overwrite )
    123 {
    124         char s[512];
    125         char path[512], new_path[512];
    126         char *line;
    127         nick_t *n;
    128         set_t *set;
    129         mode_t ou = umask( 0077 );
    130         account_t *a;
    131         FILE *fp;
    132         char *hash;
    133 
    134         if (!overwrite) {
    135                 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
    136                 if (access( path, F_OK ) != -1)
    137                         return STORAGE_ALREADY_EXISTS;
    138        
    139                 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
    140                 if (access( path, F_OK ) != -1)
    141                         return STORAGE_ALREADY_EXISTS;
    142         }
    143        
    144         /*\
    145          *  [SH] Nothing should be saved if no password is set, because the
    146          *  password is not set if it was wrong, or if one is not identified
    147          *  yet. This means that a malicious user could easily overwrite
    148          *  files owned by someone else:
    149          *  a Bad Thing, methinks
    150         \*/
    151 
    152         /* [WVG] No? Really? */
    153 
    154         /*\
    155          *  [SH] Okay, okay, it wasn't really Wilmer who said that, it was
    156          *  me. I just thought it was funny.
    157         \*/
    158        
    159         hash = hashpass( irc->password );
    160         if( hash == NULL )
    161         {
    162                 irc_usermsg( irc, "Please register yourself if you want to save your settings." );
    163                 return STORAGE_OTHER_ERROR;
    164         }
    165        
    166         g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks~" );
    167         fp = fopen( path, "w" );
    168         if( !fp ) return STORAGE_OTHER_ERROR;
    169         for( n = irc->nicks; n; n = n->next )
    170         {
    171                 strcpy( s, n->handle );
    172                 s[169] = 0; /* Prevent any overflow (169 ~ 512 / 3) */
    173                 http_encode( s );
    174                 g_snprintf( s + strlen( s ), 510 - strlen( s ), " %d %s", find_protocol_id(n->proto->name), n->nick );
    175                 if( fprintf( fp, "%s\n", s ) != strlen( s ) + 1 )
    176                 {
    177                         irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    178                         fclose( fp );
    179                         return STORAGE_OTHER_ERROR;
    180                 }
    181         }
    182         if( fclose( fp ) != 0 )
    183         {
    184                 irc_usermsg( irc, "fclose() reported an error. Disk full?" );
    185                 return STORAGE_OTHER_ERROR;
    186         }
    187  
    188         g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
    189         if( unlink( new_path ) != 0 )
    190         {
    191                 if( errno != ENOENT )
    192                 {
    193                         irc_usermsg( irc, "Error while removing old .nicks file" );
    194                         return STORAGE_OTHER_ERROR;
    195                 }
    196         }
    197         if( rename( path, new_path ) != 0 )
    198         {
    199                 irc_usermsg( irc, "Error while renaming new .nicks file" );
    200                 return STORAGE_OTHER_ERROR;
    201         }
    202        
    203         g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts~" );
    204         fp = fopen( path, "w" );
    205         if( !fp ) return STORAGE_OTHER_ERROR;
    206         if( fprintf( fp, "%s", hash ) != strlen( hash ) )
    207         {
    208                 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    209                 fclose( fp );
    210                 return STORAGE_OTHER_ERROR;
    211         }
    212         g_free( hash );
    213 
    214         for( a = irc->accounts; a; a = a->next )
    215         {
    216                 if( !strcmp(a->prpl->name, "oscar") )
    217                         g_snprintf( s, sizeof( s ), "account add oscar \"%s\" \"%s\" %s", a->user, a->pass, a->server );
    218                 else
    219                         g_snprintf( s, sizeof( s ), "account add %s \"%s\" \"%s\" \"%s\"",
    220                                     a->prpl->name, a->user, a->pass, a->server ? a->server : "" );
    221                
    222                 line = obfucrypt( s, irc->password );
    223                 if( *line )
    224                 {
    225                         if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
    226                         {
    227                                 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    228                                 fclose( fp );
    229                                 return STORAGE_OTHER_ERROR;
    230                         }
    231                 }
    232                 g_free( line );
    233         }
    234        
    235         for( set = irc->set; set; set = set->next )
    236         {
    237                 if( set->value && set->def )
    238                 {
    239                         g_snprintf( s, sizeof( s ), "set %s \"%s\"", set->key, set->value );
    240                         line = obfucrypt( s, irc->password );
    241                         if( *line )
    242                         {
    243                                 if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
    244                                 {
    245                                         irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    246                                         fclose( fp );
    247                                         return STORAGE_OTHER_ERROR;
    248                                 }
    249                         }
    250                         g_free( line );
    251                 }
    252         }
    253        
    254         if( strcmp( irc->mynick, ROOT_NICK ) != 0 )
    255         {
    256                 g_snprintf( s, sizeof( s ), "rename %s %s", ROOT_NICK, irc->mynick );
    257                 line = obfucrypt( s, irc->password );
    258                 if( *line )
    259                 {
    260                         if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
    261                         {
    262                                 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    263                                 fclose( fp );
    264                                 return STORAGE_OTHER_ERROR;
    265                         }
    266                 }
    267                 g_free( line );
    268         }
    269         if( fclose( fp ) != 0 )
    270         {
    271                 irc_usermsg( irc, "fclose() reported an error. Disk full?" );
    272                 return STORAGE_OTHER_ERROR;
    273         }
    274        
    275         g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
    276         if( unlink( new_path ) != 0 )
    277         {
    278                 if( errno != ENOENT )
    279                 {
    280                         irc_usermsg( irc, "Error while removing old .accounts file" );
    281                         return STORAGE_OTHER_ERROR;
    282                 }
    283         }
    284         if( rename( path, new_path ) != 0 )
    285         {
    286                 irc_usermsg( irc, "Error while renaming new .accounts file" );
    287                 return STORAGE_OTHER_ERROR;
    288         }
    289        
    290         umask( ou );
    291118       
    292119        return STORAGE_OK;
     
    337164        .check_pass = text_check_pass,
    338165        .remove = text_remove,
    339         .load = text_load,
    340         .save = text_save
     166        .load = text_load
    341167};
  • storage_xml.c

    r911f2eb r5b52a48  
    197197                if( xd->current_account && handle && nick )
    198198                {
    199                         nick_set( irc, handle, xd->current_account->prpl, nick );
     199                        nick_set( xd->current_account, handle, nick );
    200200                }
    201201                else
     
    365365}
    366366
     367static gboolean xml_save_nick( gpointer key, gpointer value, gpointer data );
     368
    367369static storage_status_t xml_save( irc_t *irc, int overwrite )
    368370{
    369371        char path[512], *path2, *pass_buf = NULL;
    370372        set_t *set;
    371         nick_t *nick;
    372373        account_t *acc;
    373374        int fd;
     
    440441                                        goto write_error;
    441442               
    442                 for( nick = irc->nicks; nick; nick = nick->next )
    443                         if( nick->proto == acc->prpl )
    444                                 if( !xml_printf( fd, 2, "<buddy handle=\"%s\" nick=\"%s\" />\n", nick->handle, nick->nick ) )
    445                                         goto write_error;
     443                /* This probably looks pretty strange. g_hash_table_foreach
     444                   is quite a PITA already (but it can't get much better in
     445                   C without using #define, I'm afraid), and since it
     446                   doesn't seem to be possible to abort the foreach on write
     447                   errors, so instead let's use the _find function and
     448                   return TRUE on write errors. Which means, if we found
     449                   something, there was an error. :-) */
     450                if( g_hash_table_find( acc->nicks, xml_save_nick, (gpointer) fd ) )
     451                        goto write_error;
    446452               
    447453                if( !xml_printf( fd, 1, "</account>\n" ) )
     
    476482       
    477483        return STORAGE_OTHER_ERROR;
     484}
     485
     486static gboolean xml_save_nick( gpointer key, gpointer value, gpointer data )
     487{
     488        return !xml_printf( (int) data, 2, "<buddy handle=\"%s\" nick=\"%s\" />\n", key, value );
    478489}
    479490
  • user.c

    r911f2eb r5b52a48  
    143143user_t *user_findhandle( struct gaim_connection *gc, char *handle )
    144144{
    145         user_t *u = gc->irc->users;
    146        
    147         while( u )
    148         {
    149                 if( u->gc == gc && u->handle && gc->acc->prpl->cmp_buddynames ( u->handle, handle ) == 0 )
    150                         break;
    151                 u = u->next;
    152         }
    153        
    154         return( u );
     145        user_t *u;
     146        char *nick;
     147       
     148        /* First, let's try a hash lookup. If it works, it's probably faster. */
     149        if( ( nick = g_hash_table_lookup( gc->acc->nicks, handle ) ) &&
     150            ( u = user_find( gc->irc, nick ) ) &&
     151            ( gc->acc->prpl->handle_cmp( handle, u->handle ) == 0 ) )
     152                return u;
     153       
     154        /* However, it doesn't always work, so in that case we'll have to dig
     155           through the whole userlist. :-( */
     156        for( u = gc->irc->users; u; u = u->next )
     157                if( u->gc == gc && u->handle && gc->acc->prpl->handle_cmp( u->handle, handle ) == 0 )
     158                        return u;
     159       
     160        return NULL;
    155161}
    156162
Note: See TracChangeset for help on using the changeset viewer.