aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/oscar/im.h
diff options
context:
space:
mode:
authorjgeboski <jgeboski@gmail.com>2014-12-17 12:57:17 -0500
committerjgeboski <jgeboski@gmail.com>2015-01-28 12:06:40 -0500
commit7b8238d0c9f409deaa15147bc76fc77101cb52c3 (patch)
tree10ea10fb01e94ded97600c00368ee66b1a61ab89 /protocols/oscar/im.h
parent1fa510944f3f95f1907422dc8f7cfe9238b99cd0 (diff)
irc-channel: implemented a special mode for show_users
This allows for users to be declared as being special, which does not have any specific meaning. The meaning of being special is different from protocol-to-protocol, which many protocols do not even implement. This functionality is mainly geared towards a special user state which only some protocols may actually need to define. For example, with the third-party Steam plugin, this can be used for denoting a user which is actively playing a game. By default, this mode will not actually be used by any plugin. However, it does default to the half-operator user mode.
Diffstat (limited to 'protocols/oscar/im.h')
0 files changed, 0 insertions, 0 deletions
n131'>131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
  /********************************************************************\
  * BitlBee -- An IRC to other IM-networks gateway                     *
  *                                                                    *
  * Copyright 2002-2007 Wilmer van der Gaast and others                *
  \********************************************************************/

/* Some stuff to fetch, save and handle nicknames for your buddies      */

/*
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License with
  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
  Suite 330, Boston, MA  02111-1307  USA
*/

#define BITLBEE_CORE
#include "bitlbee.h"

/* Store handles in lower case and strip spaces, because AIM is braindead. */
static char *clean_handle( const char *orig )
{
	char *new = g_malloc( strlen( orig ) + 1 );
	int i = 0;
	
	do {
		if (*orig != ' ')
			new[i++] = tolower( *orig );
	}
	while (*(orig++));
	
	return new;
}

void nick_set( account_t *acc, const char *handle, const char *nick )
{
	char *store_handle, *store_nick = g_malloc( MAX_NICK_LENGTH + 1 );
	
	store_handle = clean_handle( handle );
	strncpy( store_nick, nick, MAX_NICK_LENGTH );
	nick_strip( store_nick );
	
	g_hash_table_replace( acc->nicks, store_handle, store_nick );
}

char *nick_get( account_t *acc, const char *handle )
{
	static char nick[MAX_NICK_LENGTH+1];
	char *store_handle, *found_nick;
	
	memset( nick, 0, MAX_NICK_LENGTH + 1 );
	
	store_handle = clean_handle( handle );
	/* Find out if we stored a nick for this person already. If not, try
	   to generate a sane nick automatically. */
	if( ( found_nick = g_hash_table_lookup( acc->nicks, store_handle ) ) )
	{
		strncpy( nick, found_nick, MAX_NICK_LENGTH );
	}
	else
	{
		char *s;
		
		g_snprintf( nick, MAX_NICK_LENGTH, "%s", handle );
		if( ( s = strchr( nick, '@' ) ) )
			while( *s )
				*(s++) = 0;
		
		nick_strip( nick );
		if( set_getbool( &acc->irc->set, "lcnicks" ) )
			nick_lc( nick );
	}
	g_free( store_handle );
	
	/* Make sure the nick doesn't collide with an existing one by adding
	   underscores and that kind of stuff, if necessary. */
	nick_dedupe( acc, handle, nick );
	
	return nick;
}

void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+1] )
{
	int inf_protection = 256;
	
	/* Now, find out if the nick is already in use at the moment, and make
	   subtle changes to make it unique. */
	while( !nick_ok( nick ) || user_find( acc->irc, nick ) )
	{
		if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) )
		{
			nick[strlen(nick)+1] = 0;
			nick[strlen(nick)] = '_';
		}
		else
		{
			nick[0] ++;
		}
		
		if( inf_protection-- == 0 )
		{
			int i;
			
			irc_usermsg( acc->irc, "WARNING: Almost had an infinite loop in nick_get()! "
			                       "This used to be a fatal BitlBee bug, but we tried to fix it. "
			                       "This message should *never* appear anymore. "
			                       "If it does, please *do* send us a bug report! "
			                       "Please send all the following lines in your report:" );
			
			irc_usermsg( acc->irc, "Trying to get a sane nick for handle %s", handle );
			for( i = 0; i < MAX_NICK_LENGTH; i ++ )
				irc_usermsg( acc->irc, "Char %d: %c/%d", i, nick[i], nick[i] );
			
			irc_usermsg( acc->irc, "FAILED. Returning an insane nick now. Things might break. "
			                       "Good luck, and please don't forget to paste the lines up here "
			                       "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
			
			g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() );
			
			break;
		}
	}
}

/* Just check if there is a nickname set for this buddy or if we'd have to
   generate one. */
int nick_saved( account_t *acc, const char *handle )
{
	char *store_handle, *found;
	
	store_handle = clean_handle( handle );
	found = g_hash_table_lookup( acc->nicks, store_handle );
	g_free( store_handle );
	
	return found != NULL;
}

void nick_del( account_t *acc, const char *handle )
{
	g_hash_table_remove( acc->nicks, handle );
}


/* Character maps, _lc_[x] == _uc_[x] (but uppercase), according to the RFC's.
   With one difference, we allow dashes. */

static char *nick_lc_chars = "0123456789abcdefghijklmnopqrstuvwxyz{}^-_|";
static char *nick_uc_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[]~-_\\";

void nick_strip( char * nick )
{
	int i, j;
	
	for( i = j = 0; nick[i] && j < MAX_NICK_LENGTH; i++ )
	{
		if( strchr( nick_lc_chars, nick[i] ) || 
		    strchr( nick_uc_chars, nick[i] ) )
		{
			nick[j] = nick[i];
			j++;
		}
	}
	while( j <= MAX_NICK_LENGTH )
		nick[j++] = '\0';
}

int nick_ok( const char *nick )
{
	const char *s;
	
	/* Empty/long nicks are not allowed */
	if( !*nick || strlen( nick ) > MAX_NICK_LENGTH )
		return( 0 );
	
	for( s = nick; *s; s ++ )
		if( !strchr( nick_lc_chars, *s ) && !strchr( nick_uc_chars, *s ) )
			return( 0 );
	
	return( 1 );
}

int nick_lc( char *nick )
{
	static char tab[128] = { 0 };
	int i;
	
	if( tab['A'] == 0 )
		for( i = 0; nick_lc_chars[i]; i ++ )
		{
			tab[(int)nick_uc_chars[i]] = nick_lc_chars[i];
			tab[(int)nick_lc_chars[i]] = nick_lc_chars[i];
		}
	
	for( i = 0; nick[i]; i ++ )
	{
		if( !tab[(int)nick[i]] )
			return( 0 );
		
		nick[i] = tab[(int)nick[i]];
	}
	
	return( 1 );
}

int nick_uc( char *nick )
{
	static char tab[128] = { 0 };
	int i;
	
	if( tab['A'] == 0 )
		for( i = 0; nick_lc_chars[i]; i ++ )
		{
			tab[(int)nick_uc_chars[i]] = nick_uc_chars[i];
			tab[(int)nick_lc_chars[i]] = nick_uc_chars[i];
		}
	
	for( i = 0; nick[i]; i ++ )
	{
		if( !tab[(int)nick[i]] )
			return( 0 );
		
		nick[i] = tab[(int)nick[i]];
	}
	
	return( 1 );
}

int nick_cmp( const char *a, const char *b )
{
	char aa[1024] = "", bb[1024] = "";
	
	strncpy( aa, a, sizeof( aa ) - 1 );
	strncpy( bb, b, sizeof( bb ) - 1 );
	if( nick_lc( aa ) && nick_lc( bb ) )
	{
		return( strcmp( aa, bb ) );
	}
	else
	{
		return( -1 );	/* Hmm... Not a clear answer.. :-/ */
	}
}

char *nick_dup( const char *nick )
{
	return g_strndup( nick, MAX_NICK_LENGTH );
}