Changeset c608891
- Timestamp:
- 2013-04-23T16:20:06Z (12 years ago)
- Branches:
- master
- Children:
- 5cb9461
- Parents:
- e277e80
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
irc.c
re277e80 rc608891 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
re277e80 rc608891 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 -
nick.c
re277e80 rc608891 112 112 { 113 113 gboolean ok = FALSE; /* Set to true once the nick contains something unique. */ 114 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; 115 117 char *fmt = set_getstr( &bu->ic->acc->set, "nick_format" ) ? : 116 118 set_getstr( &bu->bee->set, "nick_format" ); … … 119 121 { 120 122 char *part = NULL, chop = '\0', *asc = NULL; 121 int len = MAX_NICK_LENGTH;122 123 123 124 if( *fmt != '%' ) … … 142 143 fmt += 2; 143 144 } 144 else if( isdigit( *fmt ) )145 {146 len = 0;147 /* Grab a number. */148 while( isdigit( *fmt ) )149 len = len * 10 + ( *(fmt++) - '0' );150 }151 145 else if( g_strncasecmp( fmt, "nick", 4 ) == 0 ) 152 146 { … … 197 191 } 198 192 193 if( !part ) 194 continue; 195 199 196 /* Credits to Josay_ in #bitlbee for this idea. //TRANSLIT 200 197 should do lossy/approximate conversions, so letters with 201 198 accents don't just get stripped. Note that it depends on 202 199 LC_CTYPE being set to something other than C/POSIX. */ 203 if( part)200 if( !( irc && irc->status & IRC_UTF8_NICKS ) ) 204 201 part = asc = g_convert_with_fallback( part, -1, "ASCII//TRANSLIT", 205 202 "UTF-8", "", NULL, NULL, NULL ); 206 203 207 if( ret->len == 0 && part && isdigit( *part ) ) 208 g_string_append_c( ret, '_' ); 209 210 while( part && *part && *part != chop && len > 0 ) 211 { 212 if( strchr( nick_lc_chars, *part ) || 213 strchr( nick_uc_chars, *part ) ) 214 g_string_append_c( ret, *part ); 215 216 part ++; 217 len --; 218 } 204 if( part ) 205 g_string_append( ret, part ); 219 206 g_free( asc ); 220 207 } 221 208 222 /* This returns NULL if the nick is empty or otherwise not ok. */ 223 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; 224 218 } 225 219 … … 247 241 if( inf_protection-- == 0 ) 248 242 { 249 int i;243 g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() ); 250 244 251 irc_rootmsg( irc, "Warning: Almost had an infinite loop in nick_get()! " 252 "This used to be a fatal BitlBee bug, but we tried to fix it. " 253 "This message should *never* appear anymore. " 254 "If it does, please *do* send us a bug report! " 255 "Please send all the following lines in your report:" ); 256 257 irc_rootmsg( irc, "Trying to get a sane nick for handle %s", bu->handle ); 258 for( i = 0; i < MAX_NICK_LENGTH; i ++ ) 259 irc_rootmsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] ); 260 261 irc_rootmsg( irc, "FAILED. Returning an insane nick now. Things might break. " 262 "Good luck, and please don't forget to paste the lines up here " 263 "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" ); 264 265 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 ); 266 251 267 252 break; … … 291 276 void nick_strip( irc_t *irc, char *nick ) 292 277 { 293 int i, j; 294 295 for( i = j = 0; nick[i] && j < MAX_NICK_LENGTH; i++ ) 296 { 297 if( strchr( nick_lc_chars, nick[i] ) || 298 strchr( nick_uc_chars, nick[i] ) ) 299 { 300 nick[j] = nick[i]; 301 j++; 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 } 302 315 } 303 316 } … … 306 319 char *orig; 307 320 321 /* First character of a nick can't be a digit, so insert an 322 underscore if necessary. */ 308 323 orig = g_strdup( nick ); 309 324 g_snprintf( nick, MAX_NICK_LENGTH, "_%s", orig ); 310 325 g_free( orig ); 311 j++;312 } 313 while( j<= MAX_NICK_LENGTH )314 nick[ j++] = '\0';315 } 316 317 intnick_ok( irc_t *irc, 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 ) 318 333 { 319 334 const char *s; … … 321 336 /* Empty/long nicks are not allowed, nor numbers at [0] */ 322 337 if( !*nick || isdigit( nick[0] ) || strlen( nick ) > MAX_NICK_LENGTH ) 323 return( 0 ); 324 325 for( s = nick; *s; s ++ ) 326 if( !strchr( nick_lc_chars, *s ) && !strchr( nick_uc_chars, *s ) ) 327 return( 0 ); 328 329 return( 1 ); 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; 330 367 } 331 368 … … 342 379 } 343 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 344 393 for( i = 0; nick[i]; i ++ ) 345 {346 if( !tab[(int)nick[i]] )347 return( 0 );348 349 394 nick[i] = tab[(int)nick[i]]; 350 } 351 352 return( 1 ); 353 } 354 355 int nick_uc( irc_t *irc, char *nick ) 356 { 357 static char tab[128] = { 0 }; 358 int i; 359 360 if( tab['A'] == 0 ) 361 for( i = 0; nick_lc_chars[i]; i ++ ) 362 { 363 tab[(int)nick_uc_chars[i]] = nick_uc_chars[i]; 364 tab[(int)nick_lc_chars[i]] = nick_uc_chars[i]; 365 } 366 367 for( i = 0; nick[i]; i ++ ) 368 { 369 if( !tab[(int)nick[i]] ) 370 return( 0 ); 371 372 nick[i] = tab[(int)nick[i]]; 373 } 374 375 return( 1 ); 395 396 return nick_ok( irc, nick ); 376 397 } 377 398 -
nick.h
re277e80 rc608891 33 33 34 34 void nick_strip( irc_t *irc, char *nick ); 35 intnick_ok( irc_t *irc, const char *nick );35 gboolean nick_ok( irc_t *irc, const char *nick ); 36 36 int nick_lc( irc_t *irc, char *nick ); 37 37 int nick_uc( irc_t *irc, char *nick );
Note: See TracChangeset
for help on using the changeset viewer.