/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2013 Wilmer van der Gaast and others * \********************************************************************/ /* The IRC-based UI - Representing (virtual) channels. */ /* 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., 51 Franklin St., Fifth Floor, Boston, MA 02110-1301 USA */ #include "bitlbee.h" static char *set_eval_channel_type(set_t *set, char *value); static gint irc_channel_user_cmp(gconstpointer a_, gconstpointer b_); static const struct irc_channel_funcs control_channel_funcs; extern const struct irc_channel_funcs irc_channel_im_chat_funcs; irc_channel_t *irc_channel_new(irc_t *irc, const char *name) { irc_channel_t *ic; set_t *s; if (!irc_channel_name_ok(name) || irc_channel_by_name(irc, name)) { return NULL; } ic = g_new0(irc_channel_t, 1); ic->irc = irc; ic->name = g_strdup(name); strcpy(ic->mode, CMODE); irc_channel_add_user(ic, irc->root); irc->channels = g_slist_append(irc->channels, ic); set_add(&ic->set, "auto_join", "false", set_eval_bool, ic); s = set_add(&ic->set, "type", "control", set_eval_channel_type, ic); s->flags |= SET_NOSAVE; /* Layer violation (XML format detail) */ if (name[0] == '&') { set_setstr(&ic->set, "type", "control"); } else { /* if( name[0] == '#' ) */ set_setstr(&ic->set, "type", "chat"); } return ic; } irc_channel_t *irc_channel_by_name(irc_t *irc, const char *name) { GSList *l; for (l = irc->channels; l; l = l->next) { irc_channel_t *ic = l->data; if (irc_channel_name_cmp(name, ic->name) == 0) { return ic; } } return NULL; } irc_channel_t *irc_channel_get(irc_t *irc, char *id) { irc_channel_t *ic, *ret = NULL; GSList *l; int nr; if (sscanf(id, "%d", &nr) == 1 && nr < 1000) { for (l = irc->channels; l; l = l->next) { ic = l->data; if ((nr--) == 0) { return ic; } } return NULL; } /* Exact match first: Partial match only sucks if there's a channel #aa and #aabb */ if ((ret = irc_channel_by_name(irc, id))) { return ret; } for (l = irc->channels; l; l = l->next) { ic = l->data; if (strstr(ic->name, id)) { /* Make sure it's a unique match. */ if (!ret) { ret = ic; } else { return NULL; } } } return ret; } int irc_channel_free(irc_channel_t *ic) { irc_t *irc; GSList *l; if (ic == NULL) { return 0; } irc = ic->irc; if (ic->flags & IRC_CHANNEL_JOINED) { irc_channel_del_user(ic, irc->user, IRC_CDU_KICK, "Cleaning up channel"); } if (ic->f->_free) { ic->f->_free(ic); } while (ic->set) { set_del(&ic->set, ic->set->key); } irc->channels = g_slist_remove(irc->channels, ic); while (ic->users) { g_free(ic->users->data); ic->users = g_slist_remove(ic->users, ic->users->data); } for (l = irc->users; l; l = l->next) { irc_user_t *iu = l->data; if (iu->last_channel == ic) { iu->last_channel = irc->default_channel; } } if (ic->pastebuf_timer) { b_event_remove(ic->pastebuf_timer); } g_free(ic->name); g_free(ic->topic); g_free(ic->topic_who); g_free(ic); return 1; } struct irc_channel_free_data { irc_t *irc; irc_channel_t *ic; char *name; }; static gboolean irc_channel_free_callback(gpointer data, gint fd, b_input_condition cond) { struct irc_channel_free_data *d = data; if (g_slist_find(irc_connection_list, d->irc) && irc_channel_by_name(d->irc, d->name) == d->ic && !(d->ic->flags & IRC_CHANNEL_JOINED)) { irc_channel_free(d->ic); } g_free(d->name); g_free(d); return FALSE; } /* Free the channel, but via the event loop, so after finishing whatever event we're currently handling. */ void irc_channel_free_soon(irc_channel_t *ic) { struct irc_channel_free_data *d = g_new0(struct irc_channel_free_data, 1); d->irc = ic->irc; d->ic = ic; d->name = g_strdup(ic->name); b_timeout_add(0, irc_channel_free_callback, d); } static char *set_eval_channel_type(set_t *set, char *value) { struct irc_channel *ic = set->data; const struct irc_channel_funcs *new; if (strcmp(
/*
* 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.
*
* Jabber
* Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
*/
#include "jabber.h"
#include "log.h"
#ifdef DEBUG
void jdebug(char *zone, const char *msgfmt, ...)
{
va_list ap;
static char loghdr[LOGSIZE_HDR];
static char logmsg[LOGSIZE_TAIL];
static int size;
/* XXX: We may want to check the sizes eventually */
size = g_snprintf(loghdr, LOGSIZE_HDR, "debug/%s %s\n", zone, msgfmt);
va_start(ap, msgfmt);
size = vsnprintf(logmsg, LOGSIZE_TAIL, loghdr, ap);
fprintf(stderr,"%s",logmsg);
return;
}
#endif /* DEBUG */