Changes in / [1a2c1c0:ab19567]
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user-guide/commands.xml
r1a2c1c0 rab19567 1620 1620 </bitlbee-setting> 1621 1621 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 1636 1622 <bitlbee-setting name="web_aware" type="string" scope="account"> 1637 1623 <default>false</default> -
ipc.c
r1a2c1c0 rab19567 152 152 old = l->data; 153 153 if( child != old && 154 old->nick && nick_cmp( NULL,old->nick, child->nick ) == 0 &&154 old->nick && nick_cmp( old->nick, child->nick ) == 0 && 155 155 old->password && strcmp( old->password, child->password ) == 0 ) 156 156 break; … … 298 298 return; 299 299 300 if( nick_cmp( NULL,cmd[1], irc->user->nick ) != 0 )300 if( nick_cmp( cmd[1], irc->user->nick ) != 0 ) 301 301 return; /* It's not for us. */ 302 302 -
irc.c
r1a2c1c0 rab19567 35 35 static char *set_eval_password( set_t *set, char *value ); 36 36 static char *set_eval_bw_compat( set_t *set, char *value ); 37 static char *set_eval_utf8_nicks( set_t *set, char *value );38 37 39 38 irc_t *irc_new( int fd ) … … 135 134 s = set_add( &b->set, "to_char", ": ", set_eval_to_char, irc ); 136 135 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 );138 136 139 137 irc->root = iu = irc_user_new( irc, ROOT_NICK ); … … 964 962 } 965 963 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 will972 be UTF-8 nicks around already so if we suddenly disable support973 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 983 964 void register_irc_plugin( const struct irc_plugin *p ) 984 965 { -
irc.h
r1a2c1c0 rab19567 62 62 OPER_HACK_ACCOUNT_ADD = 0x400, 63 63 OPER_HACK_ANY = 0x3700, /* To check for them all at once. */ 64 65 IRC_UTF8_NICKS = 0x10000, /* Disable ASCII restrictions on buddy nicks. */66 64 } irc_status_t; 67 65 -
irc_commands.c
r1a2c1c0 rab19567 80 80 irc_send_num( irc, 433, "%s :This nick is already in use", cmd[1] ); 81 81 } 82 else if( !nick_ok( NULL,cmd[1] ) )82 else if( !nick_ok( cmd[1] ) ) 83 83 { 84 84 /* [SH] Invalid characters. */ … … 291 291 else 292 292 { 293 if( nick_cmp( NULL,cmd[1], irc->user->nick ) == 0 )293 if( nick_cmp( cmd[1], irc->user->nick ) == 0 ) 294 294 { 295 295 if( cmd[2] ) … … 392 392 /* At least for now just echo. IIRC some IRC clients use self-notices 393 393 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 ) 395 395 irc_send_msg( irc->user, "NOTICE", irc->user->nick, cmd[2], NULL ); 396 396 else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) ) … … 593 593 594 594 nick = g_strdup( cmd[i] + 1 ); 595 nick_lc( irc,nick );595 nick_lc( nick ); 596 596 597 597 iu = irc_user_by_name( irc, nick ); -
irc_im.c
r1a2c1c0 rab19567 697 697 irc_channel_name_strip( stripped ); 698 698 if( set_getbool( &bee->set, "lcnicks" ) ) 699 nick_lc( irc,stripped );699 nick_lc( stripped ); 700 700 701 701 if( stripped[0] == '\0' ) -
irc_user.c
r1a2c1c0 rab19567 36 36 37 37 iu->key = g_strdup( nick ); 38 nick_lc( i rc, iu->key );38 nick_lc( iu->key ); 39 39 /* Using the hash table for speed and irc->users for easy iteration 40 40 through the list (since the GLib API doesn't have anything sane … … 107 107 108 108 strcpy( key, nick ); 109 if( nick_lc( irc,key ) )109 if( nick_lc( key ) ) 110 110 return g_hash_table_lookup( irc->nick_user_hash, key ); 111 111 else … … 121 121 122 122 strcpy( key, new ); 123 if( iu == NULL || !nick_lc( irc,key ) ||123 if( iu == NULL || !nick_lc( key ) || 124 124 ( ( new_iu = irc_user_by_name( irc, new ) ) && new_iu != iu ) ) 125 125 return 0; -
nick.c
r1a2c1c0 rab19567 51 51 { 52 52 char *store_handle, *store_nick = g_malloc( MAX_NICK_LENGTH + 1 ); 53 irc_t *irc = (irc_t *) acc->bee->ui_data;54 53 55 54 store_handle = clean_handle( handle ); 56 55 store_nick[MAX_NICK_LENGTH] = '\0'; 57 56 strncpy( store_nick, nick, MAX_NICK_LENGTH ); 58 nick_strip( irc,store_nick );57 nick_strip( store_nick ); 59 58 60 59 g_hash_table_replace( acc->nicks, store_handle, store_nick ); … … 70 69 static char nick[MAX_NICK_LENGTH+1]; 71 70 char *store_handle, *found_nick; 72 irc_t *irc = (irc_t *) bu->bee->ui_data;73 71 74 72 memset( nick, 0, MAX_NICK_LENGTH + 1 ); … … 96 94 *(s++) = 0; 97 95 98 nick_strip( irc,nick );96 nick_strip( nick ); 99 97 if( set_getbool( &bu->bee->set, "lcnicks" ) ) 100 nick_lc( irc,nick );98 nick_lc( nick ); 101 99 } 102 100 g_free( store_handle ); … … 112 110 { 113 111 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( "" ); 117 113 char *fmt = set_getstr( &bu->ic->acc->set, "nick_format" ) ? : 118 114 set_getstr( &bu->bee->set, "nick_format" ); … … 121 117 { 122 118 char *part = NULL, chop = '\0', *asc = NULL; 119 int len = MAX_NICK_LENGTH; 123 120 124 121 if( *fmt != '%' ) … … 143 140 fmt += 2; 144 141 } 142 else if( isdigit( *fmt ) ) 143 { 144 len = 0; 145 /* Grab a number. */ 146 while( isdigit( *fmt ) ) 147 len = len * 10 + ( *(fmt++) - '0' ); 148 } 145 149 else if( g_strncasecmp( fmt, "nick", 4 ) == 0 ) 146 150 { … … 191 195 } 192 196 193 if( !part )194 continue;195 196 197 /* Credits to Josay_ in #bitlbee for this idea. //TRANSLIT 197 198 should do lossy/approximate conversions, so letters with 198 199 accents don't just get stripped. Note that it depends on 199 200 LC_CTYPE being set to something other than C/POSIX. */ 200 if( !( irc && irc->status & IRC_UTF8_NICKS ))201 if( part ) 201 202 part = asc = g_convert_with_fallback( part, -1, "ASCII//TRANSLIT", 202 203 "UTF-8", "", NULL, NULL, NULL ); 203 204 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 } 206 217 g_free( asc ); 207 218 } 208 219 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 ); 218 222 } 219 223 … … 226 230 /* Now, find out if the nick is already in use at the moment, and make 227 231 subtle changes to make it unique. */ 228 while( !nick_ok( irc,nick ) ||232 while( !nick_ok( nick ) || 229 233 ( ( iu = irc_user_by_name( irc, nick ) ) && iu->bu != bu ) ) 230 234 { … … 241 245 if( inf_protection-- == 0 ) 242 246 { 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 243 263 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 );251 264 252 265 break; … … 274 287 275 288 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 } 289 void 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++; 315 300 } 316 301 } … … 319 304 char *orig; 320 305 321 /* First character of a nick can't be a digit, so insert an322 underscore if necessary. */323 306 orig = g_strdup( nick ); 324 307 g_snprintf( nick, MAX_NICK_LENGTH, "_%s", orig ); 325 308 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 315 int nick_ok( const char *nick ) 333 316 { 334 317 const char *s; … … 336 319 /* Empty/long nicks are not allowed, nor numbers at [0] */ 337 320 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 330 int nick_lc( char *nick ) 370 331 { 371 332 static char tab[128] = { 0 }; … … 379 340 } 380 341 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 393 342 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 353 int 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 376 int nick_cmp( const char *a, const char *b ) 401 377 { 402 378 char aa[1024] = "", bb[1024] = ""; … … 404 380 strncpy( aa, a, sizeof( aa ) - 1 ); 405 381 strncpy( bb, b, sizeof( bb ) - 1 ); 406 if( nick_lc( irc, aa ) && nick_lc( irc,bb ) )382 if( nick_lc( aa ) && nick_lc( bb ) ) 407 383 { 408 384 return( strcmp( aa, bb ) ); … … 413 389 } 414 390 } 391 392 char *nick_dup( const char *nick ) 393 { 394 return g_strndup( nick, MAX_NICK_LENGTH ); 395 } -
nick.h
r1a2c1c0 rab19567 31 31 int nick_saved( bee_user_t *bu ); 32 32 void nick_del( bee_user_t *bu ); 33 void nick_strip( char *nick ); 33 34 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 ); 35 int nick_ok( const char *nick ); 36 int nick_lc( char *nick ); 37 int nick_uc( char *nick ); 38 int nick_cmp( const char *a, const char *b ); 39 39 char *nick_dup( const char *nick ); -
root_commands.c
r1a2c1c0 rab19567 702 702 if( cmd[3] ) 703 703 { 704 if( !nick_ok( irc,cmd[3] ) )704 if( !nick_ok( cmd[3] ) ) 705 705 { 706 706 irc_rootmsg( irc, "The requested nick `%s' is invalid", cmd[3] ); … … 844 844 irc_rootmsg( irc, "Use /nick to change your own nickname" ); 845 845 } 846 else if( !nick_ok( irc,cmd[2] ) )846 else if( !nick_ok( cmd[2] ) ) 847 847 { 848 848 irc_rootmsg( irc, "Nick `%s' is invalid", cmd[2] ); -
storage_xml.c
r1a2c1c0 rab19567 181 181 strncpy( xd->given_nick, my_nick, MAX_NICK_LENGTH ); 182 182 xd->given_nick[MAX_NICK_LENGTH] = '\0'; 183 nick_lc( NULL,xd->given_nick );183 nick_lc( xd->given_nick ); 184 184 xd->given_pass = (char*) password; 185 185 … … 368 368 369 369 path2 = g_strdup( irc->user->nick ); 370 nick_lc( NULL,path2 );370 nick_lc( path2 ); 371 371 g_snprintf( path, sizeof( path ) - 20, "%s%s%s", global.conf->configdir, path2, ".xml" ); 372 372 g_free( path2 ); … … 424 424 425 425 lc = g_strdup( nick ); 426 nick_lc( NULL,lc );426 nick_lc( lc ); 427 427 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, lc, ".xml" ); 428 428 g_free( lc );
Note: See TracChangeset
for help on using the changeset viewer.