source: nick.c @ d323394c

Last change on this file since d323394c was d323394c, checked in by Wilmer van der Gaast <wilmer@…>, at 2007-04-20T04:49:30Z

New code to use nicknames stored in ICQ contact lists.

  • Property mode set to 100644
File size: 6.2 KB
RevLine 
[b7d3cc34]1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
[d323394c]4  * Copyright 2002-2007 Wilmer van der Gaast and others                *
[b7d3cc34]5  \********************************************************************/
6
7/* Some stuff to fetch, save and handle nicknames for your buddies      */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23  Suite 330, Boston, MA  02111-1307  USA
24*/
25
26#define BITLBEE_CORE
27#include "bitlbee.h"
28
[5b52a48]29/* Store handles in lower case and strip spaces, because AIM is braindead. */
30static char *clean_handle( const char *orig )
[b7d3cc34]31{
[5b52a48]32        char *new = g_malloc( strlen( orig ) + 1 );
33        int i = 0;
[b7d3cc34]34       
[5b52a48]35        do {
36                if (*orig != ' ')
37                        new[i++] = tolower( *orig );
[b7d3cc34]38        }
[5b52a48]39        while (*(orig++));
[b7d3cc34]40       
[5b52a48]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 );
[b7d3cc34]47       
[5b52a48]48        store_handle = clean_handle( handle );
49        strncpy( store_nick, nick, MAX_NICK_LENGTH );
50        nick_strip( store_nick );
[b7d3cc34]51       
[5b52a48]52        g_hash_table_replace( acc->nicks, store_handle, store_nick );
[b7d3cc34]53}
54
[d323394c]55char *nick_get( account_t *acc, const char *handle )
[b7d3cc34]56{
57        static char nick[MAX_NICK_LENGTH+1];
[5b52a48]58        char *store_handle, *found_nick;
[b7d3cc34]59        int inf_protection = 256;
60       
61        memset( nick, 0, MAX_NICK_LENGTH + 1 );
62       
[5b52a48]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        }
70        else
[b7d3cc34]71        {
72                char *s;
73               
74                g_snprintf( nick, MAX_NICK_LENGTH, "%s", handle );
75                if( ( s = strchr( nick, '@' ) ) )
76                        while( *s )
77                                *(s++) = 0;
78               
79                nick_strip( nick );
[5b52a48]80                if( set_getbool( &acc->irc->set, "lcnicks" ) )
[b7d3cc34]81                        nick_lc( nick );
82        }
[5b52a48]83        g_free( store_handle );
[b7d3cc34]84       
[5b52a48]85        /* Now, find out if the nick is already in use at the moment, and make
86           subtle changes to make it unique. */
87        while( !nick_ok( nick ) || user_find( acc->irc, nick ) )
[b7d3cc34]88        {
89                if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) )
90                {
91                        nick[strlen(nick)+1] = 0;
92                        nick[strlen(nick)] = '_';
93                }
94                else
95                {
96                        nick[0] ++;
97                }
98               
99                if( inf_protection-- == 0 )
100                {
101                        int i;
102                       
[5b52a48]103                        irc_usermsg( acc->irc, "WARNING: Almost had an infinite loop in nick_get()! "
104                                               "This used to be a fatal BitlBee bug, but we tried to fix it. "
105                                               "This message should *never* appear anymore. "
106                                               "If it does, please *do* send us a bug report! "
107                                               "Please send all the following lines in your report:" );
[b7d3cc34]108                       
[5b52a48]109                        irc_usermsg( acc->irc, "Trying to get a sane nick for handle %s", handle );
[b7d3cc34]110                        for( i = 0; i < MAX_NICK_LENGTH; i ++ )
[5b52a48]111                                irc_usermsg( acc->irc, "Char %d: %c/%d", i, nick[i], nick[i] );
[b7d3cc34]112                       
[5b52a48]113                        irc_usermsg( acc->irc, "FAILED. Returning an insane nick now. Things might break. "
114                                               "Good luck, and please don't forget to paste the lines up here "
115                                               "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
[b7d3cc34]116                       
117                        g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() );
118                       
119                        break;
120                }
121        }
122       
[5b52a48]123        return nick;
[b7d3cc34]124}
125
[d323394c]126/* Just check if there is a nickname set for this buddy or if we'd have to
127   generate one. */
128int nick_saved( account_t *acc, const char *handle )
129{
130        char *store_handle, *found;
131       
132        store_handle = clean_handle( handle );
133        found = g_hash_table_lookup( acc->nicks, store_handle );
134        g_free( store_handle );
135       
136        return found != NULL;
137}
138
[5b52a48]139void nick_del( account_t *acc, const char *handle )
[b7d3cc34]140{
[5b52a48]141        g_hash_table_remove( acc->nicks, handle );
[b7d3cc34]142}
143
144
145/* Character maps, _lc_[x] == _uc_[x] (but uppercase), according to the RFC's.
146   With one difference, we allow dashes. */
147
148static char *nick_lc_chars = "0123456789abcdefghijklmnopqrstuvwxyz{}^-_|";
149static char *nick_uc_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[]~-_\\";
150
151void nick_strip( char * nick )
152{
153        int i, j;
154       
[1fc2958]155        for( i = j = 0; nick[i] && j < MAX_NICK_LENGTH; i++ )
[b7d3cc34]156        {
157                if( strchr( nick_lc_chars, nick[i] ) || 
158                    strchr( nick_uc_chars, nick[i] ) )
159                {
160                        nick[j] = nick[i];
161                        j++;
162                }
163        }
[1fc2958]164        while( j <= MAX_NICK_LENGTH )
[b7d3cc34]165                nick[j++] = '\0';
166}
167
[1eddf6b]168int nick_ok( const char *nick )
[b7d3cc34]169{
[1eddf6b]170        const char *s;
[b7d3cc34]171       
172        /* Empty/long nicks are not allowed */
173        if( !*nick || strlen( nick ) > MAX_NICK_LENGTH )
174                return( 0 );
175       
176        for( s = nick; *s; s ++ )
177                if( !strchr( nick_lc_chars, *s ) && !strchr( nick_uc_chars, *s ) )
178                        return( 0 );
179       
180        return( 1 );
181}
182
183int nick_lc( char *nick )
184{
[d323394c]185        static char tab[128] = { 0 };
[b7d3cc34]186        int i;
187       
188        if( tab['A'] == 0 )
189                for( i = 0; nick_lc_chars[i]; i ++ )
190                {
191                        tab[(int)nick_uc_chars[i]] = nick_lc_chars[i];
192                        tab[(int)nick_lc_chars[i]] = nick_lc_chars[i];
193                }
194       
195        for( i = 0; nick[i]; i ++ )
196        {
197                if( !tab[(int)nick[i]] )
198                        return( 0 );
199               
200                nick[i] = tab[(int)nick[i]];
201        }
202       
203        return( 1 );
204}
205
206int nick_uc( char *nick )
207{
208        static char tab[128] = { 0 };
209        int i;
210       
211        if( tab['A'] == 0 )
212                for( i = 0; nick_lc_chars[i]; i ++ )
213                {
214                        tab[(int)nick_uc_chars[i]] = nick_uc_chars[i];
215                        tab[(int)nick_lc_chars[i]] = nick_uc_chars[i];
216                }
217       
218        for( i = 0; nick[i]; i ++ )
219        {
220                if( !tab[(int)nick[i]] )
221                        return( 0 );
222               
223                nick[i] = tab[(int)nick[i]];
224        }
225       
226        return( 1 );
227}
228
[1eddf6b]229int nick_cmp( const char *a, const char *b )
[b7d3cc34]230{
231        char aa[1024] = "", bb[1024] = "";
232       
233        strncpy( aa, a, sizeof( aa ) - 1 );
234        strncpy( bb, b, sizeof( bb ) - 1 );
235        if( nick_lc( aa ) && nick_lc( bb ) )
236        {
237                return( strcmp( aa, bb ) );
238        }
239        else
240        {
241                return( -1 );   /* Hmm... Not a clear answer.. :-/ */
242        }
243}
244
[1eddf6b]245char *nick_dup( const char *nick )
[b7d3cc34]246{
[1eddf6b]247        return g_strndup( nick, MAX_NICK_LENGTH );
[b7d3cc34]248}
Note: See TracBrowser for help on using the repository browser.