/***************************************************************************** * ignore.c * * 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 * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * * Copyright (C) 2000-2002 Chris Pinkham * Released under the terms of the GPL. * *NO WARRANTY* * * cpinkham@corp.infi.net, cpinkham@bc2va.org * http://www4.infi.net/~cpinkham/gyach/ *****************************************************************************/ #include "config.h" #include #include "gyach.h" #include "ignore.h" #include "images.h" #include "yahoochat.h" #include "main.h" #include "support.h" #include "users.h" #include "util.h" GList *regex_list = NULL; GHashTable *ignore_hash = NULL; GHashTable *mute_hash = NULL; GHashTable *regex_hash = NULL; int disp_auto_ignored = 1; int ignore_on_mults = 0; int mute_on_mults = 0; int ignore_guests = 0; int suppress_mult = 0; int first_post_is_url = 0; int first_post_is_pm = 0; int url_from_nonroom_user = 0; static void show_hash(gpointer key, gpointer value, gpointer user_data) { char buf[256]; snprintf( buf, sizeof(buf), "\t%s\n", (char *)key ); append_to_textbox( chat_window, NULL, buf ); } void ignore_add( char *user ) { char tmp_user[129]; if ( ! user ) { DBG( 11, "ignore_add( NULL )\n" ); return; } else { DBG( 11, "ignore_add( '%s' )\n", user ); } my_strncpy( tmp_user, user, sizeof(tmp_user)); lower_str( tmp_user ); if ( ! ignore_hash ) { ignore_hash = g_hash_table_new( g_str_hash, g_str_equal ); } if ( ! ignore_hash ) { return; } if ( ! g_hash_table_lookup( ignore_hash, tmp_user )) { g_hash_table_insert( ignore_hash, g_strdup( tmp_user ), g_strdup( "1" )); } } void ignore_remove( char *user ) { char tmp_user[129]; gpointer key_ptr; gpointer value_ptr; if ( ! user ) { DBG( 11, "ignore_remove( NULL )\n" ); return; } else { DBG( 11, "ignore_remove( '%s' )\n", user ); } if ( ! ignore_hash ) { return; } my_strncpy( tmp_user, user, sizeof(tmp_user)); lower_str( tmp_user ); if ( g_hash_table_lookup_extended( ignore_hash, tmp_user, &key_ptr, &value_ptr )) { g_hash_table_remove( ignore_hash, tmp_user ); if ( key_ptr ) g_free( key_ptr ); if ( value_ptr ) g_free( value_ptr ); } } int ignore_check( char *user ) { char tmp_user[129]; if ( strlen( user ) > 128 ) return( 0 ); if ( ! user ) { DBG( 11, "ignore_check( NULL )\n" ); return( 0 ); } else { DBG( 11, "ignore_check( '%s' )\n", user ); } if ( ! ignore_hash ) { return( 0 ); } my_strncpy( tmp_user, user, sizeof(tmp_user)); lower_str( tmp_user ); /* check for .guest user */ if (( ignore_guests ) && ( strlen( tmp_user ) > 6 ) && ( ! strcmp( &tmp_user[strlen(tmp_user)-6], ".guest" ))) { return( 1 ); } if ( g_hash_table_lookup( ignore_hash, tmp_user )) { return( 1 ); } return( 0 ); } void regex_add( char *regex ) { regex_t *ai_regex; if ( ! regex ) { DBG( 11, "regex_add( NULL )\n" ); return; } else { DBG( 11, "regex_add( '%s' )\n", regex ); } /* maintain the list of regex */ if ( g_list_find_custom( regex_list, regex, (GCompareFunc)gstrcmp )) return; regex_list = g_list_prepend( regex_list, g_strdup( regex )); if ( ! regex_hash ) { regex_hash = g_hash_table_new( g_str_hash, g_str_equal ); } /* maintain the hash table of compiled regex structures */ if ( ! g_hash_table_lookup( regex_hash, regex )) { ai_regex = malloc( sizeof( regex_t )); regcomp( ai_regex, regex, REG_EXTENDED | REG_ICASE | REG_NOSUB ); g_hash_table_insert( regex_hash, g_strdup( regex ), ai_regex ); } } void regex_remove( char *regex ) { GList *this_regex; gpointer key_ptr; gpointer value_ptr; char *ptr; if ( ! regex ) { DBG( 11, "regex_remove( NULL )\n" ); return; } else { DBG( 11, "regex_remove( '%s' )\n", regex ); } /* maintain the list of regex */ this_regex = g_list_find_custom( regex_list, regex, (GCompareFunc)gstrcmp ); if ( this_regex ) { ptr = this_regex->data; regex_list = g_list_remove( regex_list, ptr ); free( ptr ); } /* maintain the hash table of compiled regex structures */ if ( g_hash_table_lookup_extended( regex_hash, regex, &key_ptr, &value_ptr )) { g_hash_table_remove( regex_hash, regex ); if ( key_ptr ) g_free( key_ptr ); if ( value_ptr ) { regfree( value_ptr ); free( value_ptr ); } } } int regex_check( char *regex ) { if ( ! regex ) { DBG( 11, "regex_check( NULL )\n" ); return( 0 ); } else { DBG( 11, "regex_check( '%s' )\n", regex ); } /* quickest to check the hash table rather than the list */ if ( g_hash_table_lookup( regex_hash, regex )) { return( 1 ); } return( 0 ); } char *auto_ignore_check( char *str ) { GList *this_regex; regex_t *ai_regex; if ( ! str ) { DBG( 11, "auto_ignore_check( NULL )\n" ); return( 0 ); } else { DBG( 11, "auto_ignore_check( '%s' )\n", str ); } this_regex = regex_list; while( this_regex ) { ai_regex = g_hash_table_lookup( regex_hash, this_regex->data ); if ( ! regexec( ai_regex, str, 0, NULL, 0 )) { return( this_regex->data ); } this_regex = g_list_next( this_regex ); } return( NULL ); } void ignore_load() { char if_filename[1024]; char buf[129]; FILE *fp; DBG( 11, "ignore_load()\n" ); snprintf( if_filename, sizeof(if_filename), "%s/ignore", GYACH_CFG_COMMON_DIR ); fp = fopen( if_filename, "r" ); if ( fp ) { /* load the new list */ while( fgets( buf, 128, fp )) { /* chop the newline */ buf[strlen(buf)-1] = '\0'; if ( ! strcmp( buf, "buy_more_pepsi" )) return; ignore_add( buf ); } fclose( fp ); } snprintf( if_filename, sizeof(if_filename), "%s/ignore.regex", GYACH_CFG_DIR ); fp = fopen( if_filename, "r" ); if ( fp ) { regex_list = gyach_g_list_free( regex_list ); /* load the new list */ while( fgets( buf, 128, fp )) { /* chop the newline */ buf[strlen(buf)-1] = '\0'; regex_add( buf ); } fclose( fp ); /* regex_list = g_list_sort( regex_list, (GCompareFunc)gstrcmp ); */ } } FILE *fp; static void print_ignore_hash(gpointer key, gpointer value, gpointer user_data) { fprintf( fp, "%s\n", (char *)key ); } void ignore_save() { GList *this_regex; char if_filename[1024]; DBG( 11, "ignore_save()\n" ); snprintf( if_filename, sizeof(if_filename), "%s/ignore", GYACH_CFG_COMMON_DIR ); fp = fopen( if_filename, "w" ); if ( fp ) { if ( ignore_hash ) { g_hash_table_foreach( ignore_hash, print_ignore_hash, NULL ); } fclose( fp ); } snprintf( if_filename, sizeof(if_filename), "%s/ignore.regex", GYACH_CFG_DIR ); fp = fopen( if_filename, "w" ); if ( fp ) { this_regex = regex_list; while( this_regex ) { fprintf( fp, "%s\n", (char *)this_regex->data ); this_regex = g_list_next( this_regex ); } fclose( fp ); } } void ignore_toggle( char *user ) { int r; int i; char buf[129] = ""; GtkWidget *tmp_widget; GtkStyle *user_style; #ifdef SHOW_STATUS_PIXMAPS GdkPixmap *st_pixmap = NULL; GdkBitmap *st_mask = NULL; #else char status[5] = ""; #endif DBG( 11, "ignore_toggle( '%s' )\n", user ); r = find_user_row( user ); tmp_widget = lookup_widget( chat_window, "users" ); user_style = gtk_widget_get_style( tmp_widget ); if ( user[0] ) { if ( ignore_check( user )) { if ( mute_check( user )) { mute_remove( user ); } ignore_remove( user ); if ( r >= 0 ) { #ifdef SHOW_STATUS_PIXMAPS if ( mute_check( user )) { st_pixmap = gdk_pixmap_create_from_xpm_d( tmp_widget->window, &st_mask, &user_style->bg[GTK_STATE_NORMAL], (gchar **)pixmap_status_mute ); } else { st_pixmap = gdk_pixmap_create_from_xpm_d( tmp_widget->window, &st_mask, &user_style->bg[GTK_STATE_NORMAL], (gchar **)pixmap_status_here ); } #else strcpy( status, "" ); #endif } snprintf( buf, sizeof(buf), "*** no longer ignoring %s%s%s ***\n", YAHOO_COLOR_BLUE, user, YAHOO_COLOR_BLACK ); set_last_comment( user, "" ); } else { if ( ! strcmp( user, "buy_more_pepsi" )) return; ignore_add( user ); if ( r >= 0 ) { #ifdef SHOW_STATUS_PIXMAPS st_pixmap = gdk_pixmap_create_from_xpm_d( tmp_widget->window, &st_mask, &user_style->bg[GTK_STATE_NORMAL], (gchar **)pixmap_status_ignore ); #else strcpy( status, "IG" ); #endif } snprintf( buf, sizeof(buf), "*** ignoring %s%s%s ***\n", YAHOO_COLOR_BLUE, user, YAHOO_COLOR_BLACK ); } append_to_textbox( chat_window, NULL, buf ); } else { strcpy( buf, "*** Ignoring the following users:\n" ); append_to_textbox( chat_window, NULL, buf ); if ( ignore_hash ) { g_hash_table_foreach( ignore_hash, show_hash, NULL ); } i = g_hash_table_size( ignore_hash ); if ( i ) { snprintf( buf, sizeof(buf), "*** Ignoring %d users ***\n", i ); } else { strcpy( buf, "\tNo Users Ignored\n" ); } append_to_textbox( chat_window, NULL, buf ); } ignore_save(); if ( r < 0 ) return; #ifdef SHOW_STATUS_PIXMAPS gtk_clist_set_pixmap(GTK_CLIST(chat_users), r, 0, st_pixmap, st_mask ); gdk_pixmap_unref( st_pixmap ); gdk_bitmap_unref( st_mask ); #else gtk_clist_set_text(GTK_CLIST(chat_users), r, 0, status ); #endif set_status_room_counts(); } int ignore_count_in_room() { int i; int count = 0; char *listitem[1]; for( i = 0 ; i < GTK_CLIST(chat_users)->rows; i++ ) { gtk_clist_get_text( GTK_CLIST(chat_users), i, 1, listitem ); if ( ignore_check( listitem[0] )) { count++; } } return( count ); } int ignore_count() { if ( ! ignore_hash ) { return( 0 ); } else { return( g_hash_table_size( ignore_hash )); } } void mute_add( char *user ) { char tmp_user[129]; if ( ! user ) { DBG( 11, "mute_add( NULL )\n" ); return; } else { DBG( 11, "mute_add( '%s' )\n", user ); } my_strncpy( tmp_user, user, sizeof(tmp_user)); lower_str( tmp_user ); if ( ! mute_hash ) { mute_hash = g_hash_table_new( g_str_hash, g_str_equal ); } if ( ! g_hash_table_lookup( mute_hash, tmp_user )) { g_hash_table_insert( mute_hash, g_strdup( tmp_user ), g_strdup( "1" )); } } void mute_remove( char *user ) { char tmp_user[129]; gpointer key_ptr; gpointer value_ptr; if ( ! user ) { DBG( 11, "mute_remove( NULL )\n" ); return; } else { DBG( 11, "mute_remove( '%s' )\n", user ); } if ( ! mute_hash ) { return; } my_strncpy( tmp_user, user, sizeof(tmp_user)); lower_str( tmp_user ); if ( g_hash_table_lookup_extended( mute_hash, tmp_user, &key_ptr, &value_ptr )) { g_hash_table_remove( mute_hash, tmp_user ); if ( key_ptr ) g_free( key_ptr ); if ( value_ptr ) g_free( value_ptr ); } } int mute_check( char *user ) { char tmp_user[129]; if ( strlen( user ) > 128 ) return( 0 ); if ( ! user ) { DBG( 11, "mute_check( NULL )\n" ); return( 0 ); } else { DBG( 11, "mute_check( '%s' )\n", user ); } if ( ! mute_hash ) { return( 0 ); } my_strncpy( tmp_user, user, sizeof(tmp_user)); lower_str( tmp_user ); if ( g_hash_table_lookup( mute_hash, tmp_user )) { return( 1 ); } return( 0 ); } void mute_toggle( char *user ) { int r; int i; char buf[129] = ""; GtkWidget *tmp_widget; GtkStyle *user_style; #ifdef SHOW_STATUS_PIXMAPS GdkPixmap *st_pixmap = NULL; GdkBitmap *st_mask = NULL; #else char status[5] = ""; #endif DBG( 11, "mute_toggle( '%s' )\n", user ); r = find_user_row( user ); tmp_widget = lookup_widget( chat_window, "users" ); user_style = gtk_widget_get_style( tmp_widget ); if ( user[0] ) { if ( mute_check( user )) { mute_remove( user ); if ( r >= 0 ) { #ifdef SHOW_STATUS_PIXMAPS if ( ignore_check( user )) { st_pixmap = gdk_pixmap_create_from_xpm_d( tmp_widget->window, &st_mask, &user_style->bg[GTK_STATE_NORMAL], (gchar **)pixmap_status_ignore ); } else { st_pixmap = gdk_pixmap_create_from_xpm_d( tmp_widget->window, &st_mask, &user_style->bg[GTK_STATE_NORMAL], (gchar **)pixmap_status_here ); } #else strcpy( status, "" ); #endif } snprintf( buf, sizeof(buf), "*** no longer muting %s%s%s ***\n", YAHOO_COLOR_BLUE, user, YAHOO_COLOR_BLACK ); set_last_comment( user, "" ); } else { mute_add( user ); if ( r >= 0 ) { #ifdef SHOW_STATUS_PIXMAPS st_pixmap = gdk_pixmap_create_from_xpm_d( tmp_widget->window, &st_mask, &user_style->bg[GTK_STATE_NORMAL], (gchar **)pixmap_status_mute ); #else strcpy( status, "MU" ); #endif } snprintf( buf, sizeof(buf), "*** muting %s%s%s ***\n", YAHOO_COLOR_BLUE, user, YAHOO_COLOR_BLACK ); } append_to_textbox( chat_window, NULL, buf ); } else { strcpy( buf, "*** Muting the following users:\n" ); append_to_textbox( chat_window, NULL, buf ); if ( mute_hash ) { g_hash_table_foreach( mute_hash, show_hash, NULL ); } i = g_hash_table_size( mute_hash ); if ( i ) { snprintf( buf, sizeof(buf), "*** Muting %d users ***\n", i ); } else { strcpy( buf, "\tNo Users Muted\n" ); } append_to_textbox( chat_window, NULL, buf ); } if ( r < 0 ) return; #ifdef SHOW_STATUS_PIXMAPS gtk_clist_set_pixmap(GTK_CLIST(chat_users), r, 0, st_pixmap, st_mask ); gdk_pixmap_unref( st_pixmap ); gdk_bitmap_unref( st_mask ); #else gtk_clist_set_text(GTK_CLIST(chat_users), r, 0, status ); #endif set_status_room_counts(); } int mute_count_in_room() { int i; int count = 0; char *listitem[1]; for( i = 0 ; i < GTK_CLIST(chat_users)->rows; i++ ) { gtk_clist_get_text( GTK_CLIST(chat_users), i, 1, listitem ); if ( mute_check( listitem[0] )) { count++; } } return( count ); } void regex_toggle( char *regex ) { char buf[129] = ""; DBG( 11, "regex_toggle( '%s' )\n", regex ); if ( regex[0] ) { if ( regex_check( regex )) { regex_remove( regex ); snprintf( buf, sizeof(buf), "*** no longer auto-ignoring on regex '%s%s%s' ***\n", YAHOO_COLOR_BLUE, regex, YAHOO_COLOR_BLACK ); } else { regex_add( regex ); snprintf( buf, sizeof(buf), "*** auto-ignoring on regex '%s%s%s' ***\n", YAHOO_COLOR_BLUE, regex, YAHOO_COLOR_BLACK ); } append_to_textbox( chat_window, NULL, buf ); } ignore_save(); } int regex_match( char *regex_str, char *str ) { regex_t regex; int result = 0; regcomp( ®ex, regex_str, REG_EXTENDED | REG_ICASE | REG_NOSUB ); if ( ! regexec( ®ex, str, 0, NULL, 0 )) result = 1; regfree( ®ex ); return( result ); }