Changes in / [1a2c1c0:ab19567]


Ignore:
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • doc/user-guide/commands.xml

    r1a2c1c0 rab19567  
    16201620        </bitlbee-setting>
    16211621
    1622         <bitlbee-setting name="utf8_nicks" type="boolean" scope="global">
    1623                 <default>false</default>
    1624 
    1625                 <description>
    1626                         <para>
    1627                                 Officially, IRC nicknames are restricted to ASCII. Recently some clients and servers started supporting Unicode nicknames though. To enable UTF-8 nickname support (contacts only) in BitlBee, enable this setting.
    1628                         </para>
    1629                        
    1630                         <para>
    1631                                 To avoid confusing old clients, this setting is disabled by default. Be careful when you try it, and be prepared to be locked out of your BitlBee in case your client interacts poorly with UTF-8 nicknames.
    1632                         </para>
    1633                 </description>
    1634         </bitlbee-setting>
    1635 
    16361622        <bitlbee-setting name="web_aware" type="string" scope="account">
    16371623                <default>false</default>
  • ipc.c

    r1a2c1c0 rab19567  
    152152                old = l->data;
    153153                if( child != old &&
    154                     old->nick && nick_cmp( NULL, old->nick, child->nick ) == 0 &&
     154                    old->nick && nick_cmp( old->nick, child->nick ) == 0 &&
    155155                    old->password && strcmp( old->password, child->password ) == 0 )
    156156                        break;
     
    298298                return;
    299299       
    300         if( nick_cmp( NULL, cmd[1], irc->user->nick ) != 0 )
     300        if( nick_cmp( cmd[1], irc->user->nick ) != 0 )
    301301                return;         /* It's not for us. */
    302302       
  • irc.c

    r1a2c1c0 rab19567  
    3535static char *set_eval_password( set_t *set, char *value );
    3636static char *set_eval_bw_compat( set_t *set, char *value );
    37 static char *set_eval_utf8_nicks( set_t *set, char *value );
    3837
    3938irc_t *irc_new( int fd )
     
    135134        s = set_add( &b->set, "to_char", ": ", set_eval_to_char, irc );
    136135        s = set_add( &b->set, "typing_notice", "false", set_eval_bool, irc );
    137         s = set_add( &b->set, "utf8_nicks", "false", set_eval_utf8_nicks, irc );
    138136
    139137        irc->root = iu = irc_user_new( irc, ROOT_NICK );
     
    964962}
    965963
    966 static char *set_eval_utf8_nicks( set_t *set, char *value )
    967 {
    968         irc_t *irc = set->data;
    969         gboolean val = bool2int( value );
    970        
    971         /* Do *NOT* unset this flag in the middle of a session. There will
    972            be UTF-8 nicks around already so if we suddenly disable support
    973            for them, various functions might behave strangely. */
    974         if( val )
    975                 irc->status |= IRC_UTF8_NICKS;
    976         else if( irc->status & IRC_UTF8_NICKS )
    977                 irc_rootmsg( irc, "You need to reconnect to BitlBee for this "
    978                                   "change to take effect." );
    979        
    980         return set_eval_bool( set, value );
    981 }
    982 
    983964void register_irc_plugin( const struct irc_plugin *p )
    984965{
  • irc.h

    r1a2c1c0 rab19567  
    6262        OPER_HACK_ACCOUNT_ADD = 0x400,
    6363        OPER_HACK_ANY = 0x3700, /* To check for them all at once. */
    64        
    65         IRC_UTF8_NICKS = 0x10000, /* Disable ASCII restrictions on buddy nicks. */
    6664} irc_status_t;
    6765
  • irc_commands.c

    r1a2c1c0 rab19567  
    8080                irc_send_num( irc, 433, "%s :This nick is already in use", cmd[1] );
    8181        }
    82         else if( !nick_ok( NULL, cmd[1] ) )
     82        else if( !nick_ok( cmd[1] ) )
    8383        {
    8484                /* [SH] Invalid characters. */
     
    291291        else
    292292        {
    293                 if( nick_cmp( NULL, cmd[1], irc->user->nick ) == 0 )
     293                if( nick_cmp( cmd[1], irc->user->nick ) == 0 )
    294294                {
    295295                        if( cmd[2] )
     
    392392        /* At least for now just echo. IIRC some IRC clients use self-notices
    393393           for lag checks, so try to support that. */
    394         if( nick_cmp( NULL, cmd[1], irc->user->nick ) == 0 )
     394        if( nick_cmp( cmd[1], irc->user->nick ) == 0 )
    395395                irc_send_msg( irc->user, "NOTICE", irc->user->nick, cmd[2], NULL );
    396396        else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) )
     
    593593               
    594594                nick = g_strdup( cmd[i] + 1 );
    595                 nick_lc( irc, nick );
     595                nick_lc( nick );
    596596               
    597597                iu = irc_user_by_name( irc, nick );
  • irc_im.c

    r1a2c1c0 rab19567  
    697697        irc_channel_name_strip( stripped );
    698698        if( set_getbool( &bee->set, "lcnicks" ) )
    699                 nick_lc( irc, stripped );
     699                nick_lc( stripped );
    700700       
    701701        if( stripped[0] == '\0' )
  • irc_user.c

    r1a2c1c0 rab19567  
    3636       
    3737        iu->key = g_strdup( nick );
    38         nick_lc( irc, iu->key );
     38        nick_lc( iu->key );
    3939        /* Using the hash table for speed and irc->users for easy iteration
    4040           through the list (since the GLib API doesn't have anything sane
     
    107107       
    108108        strcpy( key, nick );
    109         if( nick_lc( irc, key ) )
     109        if( nick_lc( key ) )
    110110                return g_hash_table_lookup( irc->nick_user_hash, key );
    111111        else
     
    121121       
    122122        strcpy( key, new );
    123         if( iu == NULL || !nick_lc( irc, key ) ||
     123        if( iu == NULL || !nick_lc( key ) ||
    124124            ( ( new_iu = irc_user_by_name( irc, new ) ) && new_iu != iu ) )
    125125                return 0;
  • nick.c

    r1a2c1c0 rab19567  
    5151{
    5252        char *store_handle, *store_nick = g_malloc( MAX_NICK_LENGTH + 1 );
    53         irc_t *irc = (irc_t *) acc->bee->ui_data;
    5453       
    5554        store_handle = clean_handle( handle );
    5655        store_nick[MAX_NICK_LENGTH] = '\0';
    5756        strncpy( store_nick, nick, MAX_NICK_LENGTH );
    58         nick_strip( irc, store_nick );
     57        nick_strip( store_nick );
    5958       
    6059        g_hash_table_replace( acc->nicks, store_handle, store_nick );
     
    7069        static char nick[MAX_NICK_LENGTH+1];
    7170        char *store_handle, *found_nick;
    72         irc_t *irc = (irc_t *) bu->bee->ui_data;
    7371       
    7472        memset( nick, 0, MAX_NICK_LENGTH + 1 );
     
    9694                                *(s++) = 0;
    9795               
    98                 nick_strip( irc, nick );
     96                nick_strip( nick );
    9997                if( set_getbool( &bu->bee->set, "lcnicks" ) )
    100                         nick_lc( irc, nick );
     98                        nick_lc( nick );
    10199        }
    102100        g_free( store_handle );
     
    112110{
    113111        gboolean ok = FALSE; /* Set to true once the nick contains something unique. */
    114         GString *ret = g_string_sized_new( MAX_NICK_LENGTH + 1 );
    115         char *rets;
    116         irc_t *irc = (irc_t *) bu->bee->ui_data;
     112        GString *ret = g_string_new( "" );
    117113        char *fmt = set_getstr( &bu->ic->acc->set, "nick_format" ) ? :
    118114                    set_getstr( &bu->bee->set, "nick_format" );
     
    121117        {
    122118                char *part = NULL, chop = '\0', *asc = NULL;
     119                int len = MAX_NICK_LENGTH;
    123120               
    124121                if( *fmt != '%' )
     
    143140                                fmt += 2;
    144141                        }
     142                        else if( isdigit( *fmt ) )
     143                        {
     144                                len = 0;
     145                                /* Grab a number. */
     146                                while( isdigit( *fmt ) )
     147                                        len = len * 10 + ( *(fmt++) - '0' );
     148                        }
    145149                        else if( g_strncasecmp( fmt, "nick", 4 ) == 0 )
    146150                        {
     
    191195                }
    192196               
    193                 if( !part )
    194                         continue;
    195                
    196197                /* Credits to Josay_ in #bitlbee for this idea. //TRANSLIT
    197198                   should do lossy/approximate conversions, so letters with
    198199                   accents don't just get stripped. Note that it depends on
    199200                   LC_CTYPE being set to something other than C/POSIX. */
    200                 if( !( irc && irc->status & IRC_UTF8_NICKS ) )
     201                if( part )
    201202                        part = asc = g_convert_with_fallback( part, -1, "ASCII//TRANSLIT",
    202203                                                              "UTF-8", "", NULL, NULL, NULL );
    203204               
    204                 if( part )
    205                         g_string_append( ret, part );
     205                if( ret->len == 0 && part && isdigit( *part ) )
     206                        g_string_append_c( ret, '_' );
     207               
     208                while( part && *part && *part != chop && len > 0 )
     209                {
     210                        if( strchr( nick_lc_chars, *part ) ||
     211                            strchr( nick_uc_chars, *part ) )
     212                                g_string_append_c( ret, *part );
     213                       
     214                        part ++;
     215                        len --;
     216                }
    206217                g_free( asc );
    207218        }
    208219       
    209         rets = g_string_free( ret, FALSE );
    210         if( ok && rets && *rets )
    211         {
    212                 nick_strip( irc, rets );
    213                 rets[MAX_NICK_LENGTH] = '\0';
    214                 return rets;
    215         }
    216         g_free( rets );
    217         return NULL;
     220        /* This returns NULL if the nick is empty or otherwise not ok. */
     221        return g_string_free( ret, ret->len == 0 || !ok );
    218222}
    219223
     
    226230        /* Now, find out if the nick is already in use at the moment, and make
    227231           subtle changes to make it unique. */
    228         while( !nick_ok( irc, nick ) ||
     232        while( !nick_ok( nick ) ||
    229233               ( ( iu = irc_user_by_name( irc, nick ) ) && iu->bu != bu ) )
    230234        {
     
    241245                if( inf_protection-- == 0 )
    242246                {
     247                        int i;
     248                       
     249                        irc_rootmsg( irc, "Warning: Almost had an infinite loop in nick_get()! "
     250                                          "This used to be a fatal BitlBee bug, but we tried to fix it. "
     251                                          "This message should *never* appear anymore. "
     252                                          "If it does, please *do* send us a bug report! "
     253                                          "Please send all the following lines in your report:" );
     254                       
     255                        irc_rootmsg( irc, "Trying to get a sane nick for handle %s", bu->handle );
     256                        for( i = 0; i < MAX_NICK_LENGTH; i ++ )
     257                                irc_rootmsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] );
     258                       
     259                        irc_rootmsg( irc, "FAILED. Returning an insane nick now. Things might break. "
     260                                          "Good luck, and please don't forget to paste the lines up here "
     261                                          "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
     262                       
    243263                        g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() );
    244                        
    245                         irc_rootmsg( irc, "Warning: Something went wrong while trying "
    246                                           "to generate a nickname for contact %s on %s.",
    247                                           bu->handle, bu->ic->acc->tag );
    248                         irc_rootmsg( irc, "This might be a bug in BitlBee, or the result "
    249                                           "of a faulty nick_format setting. Will use %s "
    250                                           "instead.", nick );
    251264                       
    252265                        break;
     
    274287
    275288
    276 void nick_strip( irc_t *irc, char *nick )
    277 {
    278         int len = 0;
    279        
    280         if( irc && ( irc->status & IRC_UTF8_NICKS ) )
    281         {
    282                 gunichar c;
    283                 char *p = nick, *n, tmp[strlen(nick)+1];
    284                
    285                 while( p && *p )
    286                 {
    287                         c = g_utf8_get_char_validated( p, -1 );
    288                         n = g_utf8_find_next_char( p, NULL );
    289                        
    290                         if( ( c < 0x7f && !( strchr( nick_lc_chars, c ) ||
    291                                              strchr( nick_uc_chars, c ) ) ) ||
    292                             !g_unichar_isgraph( c ) )
    293                         {
    294                                 strcpy( tmp, n );
    295                                 strcpy( p, tmp );
    296                         }
    297                         else
    298                                 p = n;
    299                 }
    300                 if( p )
    301                         len = p - nick;
    302         }
    303         else
    304         {
    305                 int i;
    306                
    307                 for( i = len = 0; nick[i] && len < MAX_NICK_LENGTH; i++ )
    308                 {
    309                         if( strchr( nick_lc_chars, nick[i] ) ||
    310                             strchr( nick_uc_chars, nick[i] ) )
    311                         {
    312                                 nick[len] = nick[i];
    313                                 len++;
    314                         }
     289void nick_strip( char *nick )
     290{
     291        int i, j;
     292       
     293        for( i = j = 0; nick[i] && j < MAX_NICK_LENGTH; i++ )
     294        {
     295                if( strchr( nick_lc_chars, nick[i] ) ||
     296                    strchr( nick_uc_chars, nick[i] ) )
     297                {
     298                        nick[j] = nick[i];
     299                        j++;
    315300                }
    316301        }
     
    319304                char *orig;
    320305               
    321                 /* First character of a nick can't be a digit, so insert an
    322                    underscore if necessary. */
    323306                orig = g_strdup( nick );
    324307                g_snprintf( nick, MAX_NICK_LENGTH, "_%s", orig );
    325308                g_free( orig );
    326                 len ++;
    327         }
    328         while( len <= MAX_NICK_LENGTH )
    329                 nick[len++] = '\0';
    330 }
    331 
    332 gboolean nick_ok( irc_t *irc, const char *nick )
     309                j ++;
     310        }
     311        while( j <= MAX_NICK_LENGTH )
     312                nick[j++] = '\0';
     313}
     314
     315int nick_ok( const char *nick )
    333316{
    334317        const char *s;
     
    336319        /* Empty/long nicks are not allowed, nor numbers at [0] */
    337320        if( !*nick || isdigit( nick[0] ) || strlen( nick ) > MAX_NICK_LENGTH )
    338                 return 0;
    339        
    340         if( irc && ( irc->status & IRC_UTF8_NICKS ) )
    341         {
    342                 gunichar c;
    343                 const char *p = nick, *n;
    344                
    345                 while( p && *p )
    346                 {
    347                         c = g_utf8_get_char_validated( p, -1 );
    348                         n = g_utf8_find_next_char( p, NULL );
    349                        
    350                         if( ( c < 0x7f && !( strchr( nick_lc_chars, c ) ||
    351                                              strchr( nick_uc_chars, c ) ) ) ||
    352                             !g_unichar_isgraph( c ) )
    353                         {
    354                                 return FALSE;
    355                         }
    356                         p = n;
    357                 }
    358         }
    359         else
    360         {
    361                 for( s = nick; *s; s ++ )
    362                         if( !strchr( nick_lc_chars, *s ) && !strchr( nick_uc_chars, *s ) )
    363                                 return FALSE;
    364         }
    365        
    366         return TRUE;
    367 }
    368 
    369 int nick_lc( irc_t *irc, char *nick )
     321                return( 0 );
     322       
     323        for( s = nick; *s; s ++ )
     324                if( !strchr( nick_lc_chars, *s ) && !strchr( nick_uc_chars, *s ) )
     325                        return( 0 );
     326       
     327        return( 1 );
     328}
     329
     330int nick_lc( char *nick )
    370331{
    371332        static char tab[128] = { 0 };
     
    379340                }
    380341       
    381         if( irc && ( irc->status & IRC_UTF8_NICKS ) )
    382         {
    383                 gchar *down = g_utf8_strdown( nick, -1 );
    384                 if( strlen( down ) > strlen( nick ) )
    385                 {
    386                         /* Well crap. Corrupt it if we have to. */
    387                         down[strlen(nick)] = '\0';
    388                 }
    389                 strcpy( nick, down );
    390                 g_free( down );
    391         }
    392        
    393342        for( i = 0; nick[i]; i ++ )
    394                 if( nick[i] < 0x7f )
    395                         nick[i] = tab[(int)nick[i]];
    396        
    397         return nick_ok( irc, nick );
    398 }
    399 
    400 int nick_cmp( irc_t *irc, const char *a, const char *b )
     343        {
     344                if( !tab[(int)nick[i]] )
     345                        return( 0 );
     346               
     347                nick[i] = tab[(int)nick[i]];
     348        }
     349       
     350        return( 1 );
     351}
     352
     353int nick_uc( char *nick )
     354{
     355        static char tab[128] = { 0 };
     356        int i;
     357       
     358        if( tab['A'] == 0 )
     359                for( i = 0; nick_lc_chars[i]; i ++ )
     360                {
     361                        tab[(int)nick_uc_chars[i]] = nick_uc_chars[i];
     362                        tab[(int)nick_lc_chars[i]] = nick_uc_chars[i];
     363                }
     364       
     365        for( i = 0; nick[i]; i ++ )
     366        {
     367                if( !tab[(int)nick[i]] )
     368                        return( 0 );
     369               
     370                nick[i] = tab[(int)nick[i]];
     371        }
     372       
     373        return( 1 );
     374}
     375
     376int nick_cmp( const char *a, const char *b )
    401377{
    402378        char aa[1024] = "", bb[1024] = "";
     
    404380        strncpy( aa, a, sizeof( aa ) - 1 );
    405381        strncpy( bb, b, sizeof( bb ) - 1 );
    406         if( nick_lc( irc, aa ) && nick_lc( irc, bb ) )
     382        if( nick_lc( aa ) && nick_lc( bb ) )
    407383        {
    408384                return( strcmp( aa, bb ) );
     
    413389        }
    414390}
     391
     392char *nick_dup( const char *nick )
     393{
     394        return g_strndup( nick, MAX_NICK_LENGTH );
     395}
  • nick.h

    r1a2c1c0 rab19567  
    3131int nick_saved( bee_user_t *bu );
    3232void nick_del( bee_user_t *bu );
     33void nick_strip( char *nick );
    3334
    34 void nick_strip( irc_t *irc, char *nick );
    35 gboolean nick_ok( irc_t *irc, const char *nick );
    36 int nick_lc( irc_t *irc, char *nick );
    37 int nick_uc( irc_t *irc, char *nick );
    38 int nick_cmp( irc_t *irc, const char *a, const char *b );
     35int nick_ok( const char *nick );
     36int nick_lc( char *nick );
     37int nick_uc( char *nick );
     38int nick_cmp( const char *a, const char *b );
    3939char *nick_dup( const char *nick );
  • root_commands.c

    r1a2c1c0 rab19567  
    702702        if( cmd[3] )
    703703        {
    704                 if( !nick_ok( irc, cmd[3] ) )
     704                if( !nick_ok( cmd[3] ) )
    705705                {
    706706                        irc_rootmsg( irc, "The requested nick `%s' is invalid", cmd[3] );
     
    844844                irc_rootmsg( irc, "Use /nick to change your own nickname" );
    845845        }
    846         else if( !nick_ok( irc, cmd[2] ) )
     846        else if( !nick_ok( cmd[2] ) )
    847847        {
    848848                irc_rootmsg( irc, "Nick `%s' is invalid", cmd[2] );
  • storage_xml.c

    r1a2c1c0 rab19567  
    181181        strncpy( xd->given_nick, my_nick, MAX_NICK_LENGTH );
    182182        xd->given_nick[MAX_NICK_LENGTH] = '\0';
    183         nick_lc( NULL, xd->given_nick );
     183        nick_lc( xd->given_nick );
    184184        xd->given_pass = (char*) password;
    185185       
     
    368368       
    369369        path2 = g_strdup( irc->user->nick );
    370         nick_lc( NULL, path2 );
     370        nick_lc( path2 );
    371371        g_snprintf( path, sizeof( path ) - 20, "%s%s%s", global.conf->configdir, path2, ".xml" );
    372372        g_free( path2 );
     
    424424
    425425        lc = g_strdup( nick );
    426         nick_lc( NULL, lc );
     426        nick_lc( lc );
    427427        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, lc, ".xml" );
    428428        g_free( lc );
Note: See TracChangeset for help on using the changeset viewer.