Changes in / [ab19567:1a2c1c0]
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user-guide/commands.xml
rab19567 r1a2c1c0 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 1622 1636 <bitlbee-setting name="web_aware" type="string" scope="account"> 1623 1637 <default>false</default> -
ipc.c
rab19567 r1a2c1c0 152 152 old = l->data; 153 153 if( child != old && 154 old->nick && nick_cmp( old->nick, child->nick ) == 0 &&154 old->nick && nick_cmp( NULL, 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( cmd[1], irc->user->nick ) != 0 )300 if( nick_cmp( NULL, cmd[1], irc->user->nick ) != 0 ) 301 301 return; /* It's not for us. */ 302 302 -
irc.c
rab19567 r1a2c1c0 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 ); 37 38 38 39 irc_t *irc_new( int fd ) … … 134 135 s = set_add( &b->set, "to_char", ": ", set_eval_to_char, irc ); 135 136 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 ); 136 138 137 139 irc->root = iu = irc_user_new( irc, ROOT_NICK ); … … 962 964 } 963 965 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 964 983 void register_irc_plugin( const struct irc_plugin *p ) 965 984 { -
irc.h
rab19567 r1a2c1c0 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. */ 64 66 } irc_status_t; 65 67 -
irc_commands.c
rab19567 r1a2c1c0 80 80 irc_send_num( irc, 433, "%s :This nick is already in use", cmd[1] ); 81 81 } 82 else if( !nick_ok( cmd[1] ) )82 else if( !nick_ok( NULL, cmd[1] ) ) 83 83 { 84 84 /* [SH] Invalid characters. */ … … 291 291 else 292 292 { 293 if( nick_cmp( cmd[1], irc->user->nick ) == 0 )293 if( nick_cmp( NULL, 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( cmd[1], irc->user->nick ) == 0 )394 if( nick_cmp( NULL, 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( nick );595 nick_lc( irc, nick ); 596 596 597 597 iu = irc_user_by_name( irc, nick ); -
irc_im.c
rab19567 r1a2c1c0 697 697 irc_channel_name_strip( stripped ); 698 698 if( set_getbool( &bee->set, "lcnicks" ) ) 699 nick_lc( stripped );699 nick_lc( irc, stripped ); 700 700 701 701 if( stripped[0] == '\0' ) -
irc_user.c
rab19567 r1a2c1c0 36 36 37 37 iu->key = g_strdup( nick ); 38 nick_lc( i u->key );38 nick_lc( irc, 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( key ) )109 if( nick_lc( irc, 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( key ) ||123 if( iu == NULL || !nick_lc( irc, key ) || 124 124 ( ( new_iu = irc_user_by_name( irc, new ) ) && new_iu != iu ) ) 125 125 return 0; -
nick.c
rab19567 r1a2c1c0 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; 53 54 54 55 store_handle = clean_handle( handle ); 55 56 store_nick[MAX_NICK_LENGTH] = '\0'; 56 57 strncpy( store_nick, nick, MAX_NICK_LENGTH ); 57 nick_strip( store_nick );58 nick_strip( irc, store_nick ); 58 59 59 60 g_hash_table_replace( acc->nicks, store_handle, store_nick ); … … 69 70 static char nick[MAX_NICK_LENGTH+1]; 70 71 char *store_handle, *found_nick; 72 irc_t *irc = (irc_t *) bu->bee->ui_data; 71 73 72 74 memset( nick, 0, MAX_NICK_LENGTH + 1 ); … … 94 96 *(s++) = 0; 95 97 96 nick_strip( nick );98 nick_strip( irc, nick ); 97 99 if( set_getbool( &bu->bee->set, "lcnicks" ) ) 98 nick_lc( nick );100 nick_lc( irc, nick ); 99 101 } 100 102 g_free( store_handle ); … … 110 112 { 111 113 gboolean ok = FALSE; /* Set to true once the nick contains something unique. */ 112 GString *ret = g_string_new( "" ); 114 GString *ret = g_string_sized_new( MAX_NICK_LENGTH + 1 ); 115 char *rets; 116 irc_t *irc = (irc_t *) bu->bee->ui_data; 113 117 char *fmt = set_getstr( &bu->ic->acc->set, "nick_format" ) ? : 114 118 set_getstr( &bu->bee->set, "nick_format" ); … … 117 121 { 118 122 char *part = NULL, chop = '\0', *asc = NULL; 119 int len = MAX_NICK_LENGTH;120 123 121 124 if( *fmt != '%' ) … … 140 143 fmt += 2; 141 144 } 142 else if( isdigit( *fmt ) )143 {144 len = 0;145 /* Grab a number. */146 while( isdigit( *fmt ) )147 len = len * 10 + ( *(fmt++) - '0' );148 }149 145 else if( g_strncasecmp( fmt, "nick", 4 ) == 0 ) 150 146 { … … 195 191 } 196 192 193 if( !part ) 194 continue; 195 197 196 /* Credits to Josay_ in #bitlbee for this idea. //TRANSLIT 198 197 should do lossy/approximate conversions, so letters with 199 198 accents don't just get stripped. Note that it depends on 200 199 LC_CTYPE being set to something other than C/POSIX. */ 201 if( part)200 if( !( irc && irc->status & IRC_UTF8_NICKS ) ) 202 201 part = asc = g_convert_with_fallback( part, -1, "ASCII//TRANSLIT", 203 202 "UTF-8", "", NULL, NULL, NULL ); 204 203 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 } 204 if( part ) 205 g_string_append( ret, part ); 217 206 g_free( asc ); 218 207 } 219 208 220 /* This returns NULL if the nick is empty or otherwise not ok. */ 221 return g_string_free( ret, ret->len == 0 || !ok ); 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; 222 218 } 223 219 … … 230 226 /* Now, find out if the nick is already in use at the moment, and make 231 227 subtle changes to make it unique. */ 232 while( !nick_ok( nick ) ||228 while( !nick_ok( irc, nick ) || 233 229 ( ( iu = irc_user_by_name( irc, nick ) ) && iu->bu != bu ) ) 234 230 { … … 245 241 if( inf_protection-- == 0 ) 246 242 { 247 int i;243 g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() ); 248 244 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 263 g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() ); 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 ); 264 251 265 252 break; … … 287 274 288 275 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++; 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 } 300 315 } 301 316 } … … 304 319 char *orig; 305 320 321 /* First character of a nick can't be a digit, so insert an 322 underscore if necessary. */ 306 323 orig = g_strdup( nick ); 307 324 g_snprintf( nick, MAX_NICK_LENGTH, "_%s", orig ); 308 325 g_free( orig ); 309 j++;310 } 311 while( j<= MAX_NICK_LENGTH )312 nick[ j++] = '\0';313 } 314 315 int nick_ok(const char *nick )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 ) 316 333 { 317 334 const char *s; … … 319 336 /* Empty/long nicks are not allowed, nor numbers at [0] */ 320 337 if( !*nick || isdigit( nick[0] ) || strlen( nick ) > MAX_NICK_LENGTH ) 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 ) 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 ) 331 370 { 332 371 static char tab[128] = { 0 }; … … 340 379 } 341 380 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 342 393 for( i = 0; nick[i]; i ++ ) 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 ) 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 ) 377 401 { 378 402 char aa[1024] = "", bb[1024] = ""; … … 380 404 strncpy( aa, a, sizeof( aa ) - 1 ); 381 405 strncpy( bb, b, sizeof( bb ) - 1 ); 382 if( nick_lc( aa ) && nick_lc(bb ) )406 if( nick_lc( irc, aa ) && nick_lc( irc, bb ) ) 383 407 { 384 408 return( strcmp( aa, bb ) ); … … 389 413 } 390 414 } 391 392 char *nick_dup( const char *nick )393 {394 return g_strndup( nick, MAX_NICK_LENGTH );395 } -
nick.h
rab19567 r1a2c1c0 31 31 int nick_saved( bee_user_t *bu ); 32 32 void nick_del( bee_user_t *bu ); 33 void nick_strip( char *nick );34 33 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 ); 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 ); 39 39 char *nick_dup( const char *nick ); -
root_commands.c
rab19567 r1a2c1c0 702 702 if( cmd[3] ) 703 703 { 704 if( !nick_ok( cmd[3] ) )704 if( !nick_ok( irc, 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( cmd[2] ) )846 else if( !nick_ok( irc, cmd[2] ) ) 847 847 { 848 848 irc_rootmsg( irc, "Nick `%s' is invalid", cmd[2] ); -
storage_xml.c
rab19567 r1a2c1c0 181 181 strncpy( xd->given_nick, my_nick, MAX_NICK_LENGTH ); 182 182 xd->given_nick[MAX_NICK_LENGTH] = '\0'; 183 nick_lc( xd->given_nick );183 nick_lc( NULL, 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( path2 );370 nick_lc( NULL, 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( lc );426 nick_lc( NULL, 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.