home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Linux
/
Divers
/
yagirc-0.51.tar.gz
/
yagirc-0.51.tar
/
yagirc-0.51
/
events-numeric.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-05-09
|
12KB
|
466 lines
/*
events-numeric.c : Functions to handle (numeric) IRC server replies
Copyright (C) 1998 Timo Sirainen
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <sys/time.h>
#include <glib.h>
#include "os.h"
#include "irc.h"
#include "txt.h"
#include "gui.h"
#include "ctcp.h"
#include "events.h"
#include "script.h"
static char tmpstr[600];
static CHAN_REC *names_chan; /* /NAMES */
static GList *ison_users, *ison_tempusers; /* /ISON */
/* Initialize events */
void events_init(void)
{
names_chan = NULL;
ison_users = NULL;
ison_tempusers = NULL;
}
void events_deinit(void)
{
GList *tmp;
for (tmp = g_list_first(ison_users); tmp != NULL; tmp = tmp->next)
g_free(tmp->data);
g_list_free(ison_users);
}
/* Get next parameter */
char *event_get_param(char **data)
{
char *pos;
g_return_val_if_fail(data != NULL, NULL);
g_return_val_if_fail(*data != NULL, NULL);
if (**data == ':')
{
pos = *data;
*data += strlen(*data);
return pos+1; /* easy. :) */
}
pos = *data;
while (**data != '\0' && **data != ' ') (*data)++;
if (**data == ' ') *(*data)++ = '\0';
return pos;
}
/* Get next count parameters from data */
char *event_get_params(char *data, int count, ...)
{
char **str, *tmp;
va_list args;
va_start(args, count);
while (count-- > 0)
{
str = (char **) va_arg(args, char **);
tmp = event_get_param(&data);
if (str != NULL) *str = tmp;
}
va_end(args);
return data;
}
void eirc_welcome(char *data)
{
/* first welcome message found - we're connected now! */
eserver->connected = 1;
return;
}
void eirc_connected(char *data)
{
/* last welcome message found - commands can be sent to server now. */
#ifdef USE_SCRIPT
char *tmp;
tmp = (char *) g_malloc(strlen(eserver->name)+20);
sprintf(tmp, "%d %s", eserver->handle, eserver->name);
script_event(eserver, esendnick, esendaddr, "CONNECTED", tmp);
g_free(tmp);
#endif
gui_connected(eserver, 1);
}
void eirc_nick_in_use(char *data)
{
char *nick;
if (eserver->connected)
return; /* Already connected, no need to handle this anymore. */
/* nick already in use - need to change it .. */
nick = eserver->nick;
if (strlen(nick) < 9)
strcpy(nick+strlen(nick), "_");
else
{
int n;
/* keep adding numbers to end of nick */
for (n = 8; n > 0; n--)
{
if (nick[n] < '0' || nick[n] > '9')
{
nick[n] = '1';
break;
}
else
{
if (nick[n] < '9')
{
nick[n]++;
break;
}
else
nick[n] = '0';
}
}
}
eserver->connected = 1;
sprintf(tmpstr, "NICK %s", nick);
irc_send_cmd(eserver, tmpstr);
eserver->connected = 0;
}
void eirc_names_list(char *data)
{
char *type, *channel, *names, *ptr;
g_return_if_fail(data != NULL);
/* type = '=' = public, '*' = private, '@' = secret */
event_get_params(data, 4, NULL, &type, &channel, &names);
drawtext(edefwin, TXT_TYPE_SERVER_TEXT, IRCTXT_NAMES, channel, names);
if (names_chan == NULL)
{
names_chan = channel_joined(eserver, channel);
if (names_chan == NULL) return;
if (names_chan->nicks != NULL)
{
GList *tmp;
for (tmp = g_list_first(names_chan->nicks); tmp != NULL; tmp = tmp->next)
g_free(tmp->data);
g_list_free(names_chan->nicks);
}
names_chan->nicks = NULL;
}
while (*names != '\0')
{
while (*names == ' ') names++;
ptr = names;
while (*names != '\0' && *names != ' ') names++;
if (*names != '\0') *names++ = '\0';
names_chan->nicks = g_list_insert_sorted(names_chan->nicks, g_strdup(ptr), (GCompareFunc) irc_nicks_compare);
}
}
void eirc_end_of_names(char *data)
{
char *chan;
event_get_params(data, 2, NULL, &chan);
drawtext(edefwin, TXT_TYPE_SERVER_TEXT, IRCTXT_ENDOFNAMES, chan);
if (names_chan != NULL) gui_nicklist_redraw(names_chan->window);
names_chan = NULL;
}
void eirc_topic(char *data)
{
CHAN_REC *chan;
char *channame, *topic;
g_return_if_fail(data != NULL);
event_get_params(data, 3, NULL, &channame, &topic);
chan = channel_joined(eserver, channame);
if (channame == NULL) return;
if (chan->topic != NULL) g_free(chan->topic);
chan->topic = *topic == '\0' ? NULL : g_strdup(topic);
if (chan->topic != NULL)
drawtext(chan->window, TXT_TYPE_SERVER_TEXT, IRCTXT_TOPIC, chan->name, chan->topic);
gui_change_topic(chan);
}
void eirc_topic_info(char *data)
{
CHAN_REC *chan;
time_t t;
struct tm *tim;
char timestr[100], *channame, *topicby, *topictime;
g_return_if_fail(data != NULL);
event_get_params(data, 4, NULL, &channame, &topicby, &topictime);
chan = channel_joined(eserver, channame);
if (chan == NULL) return;
if (sscanf(topictime, "%lu", &t) != 1) t = 0; /* topic set date */
tim = localtime(&t);
strcpy(timestr, asctime(tim));
if (timestr[strlen(timestr)-1] == '\n') timestr[strlen(timestr)-1] = '\0';
drawtext(chan->window, TXT_TYPE_SERVER_TEXT, IRCTXT_TOPIC_INFO, topicby, timestr);
}
void eirc_who(char *data)
{
char *nick, *channel, *user, *host, *status, *realname;
g_return_if_fail(data != NULL);
event_get_params(data, 8, NULL, &channel, &user, &host, NULL, &nick, &status, &realname);
/* skip hop count */
while (*realname != '\0' && *realname != ' ') realname++;
while (*realname == ' ') realname++;
sprintf(tmpstr, "%-10s %%_%-9s %-3s%%_ %s@%s (%%!%s%%!)\n", channel, nick, status, user, host, realname);
drawtext(edefwin, TXT_TYPE_SERVER_TEXT, tmpstr);
}
void eirc_ban_list(char *data)
{
char *chan, *ban, *setby, *tims;
long secs, tim;
CHAN_REC *ch;
g_return_if_fail(data != NULL);
event_get_params(data, 5, NULL, &chan, &ban, &setby, &tims);
ch = channel_joined(eserver, chan);
if (sscanf(tims, "%lu", &tim) != 1) tim = 0;
secs = time(NULL)-tim;
drawtext(ch != NULL ? ch->window : edefwin, TXT_TYPE_SERVER_TEXT, IRCTXT_BANLIST,
chan, ban, setby, secs);
}
void eirc_end_of_banlist(char *data)
{
g_return_if_fail(data != NULL);
}
void eirc_ison(char *data)
{
char *online;
GList *tmp, *next;
g_return_if_fail(data != NULL);
event_get_params(data, 2, NULL, &online);
if (eserver->ison_reqs <= 0)
{
/* user wrote /ISON.. */
if (eserver->ison_reqs < 0) eserver->ison_reqs++;
drawtext(curwin, TXT_TYPE_SERVER_TEXT, IRCTXT_ONLINE, online);
return;
}
/* we're trying to find out who of the notify list members are in IRC */
while (online != NULL && *online != '\0')
{
char *ptr;
ptr = strchr(online, ' ');
if (ptr != NULL) *ptr++ = '\0';
ison_tempusers = g_list_append(ison_tempusers, g_strdup(online));
online = ptr;
}
if (--eserver->ison_reqs == 0)
{
/* all /ISON requests got - scan through notify list to check who's
came and who's left */
/* first check who's came to irc */
for (tmp = g_list_first(ison_tempusers); tmp != NULL; tmp = tmp->next)
{
GList *on;
for (on = g_list_first(ison_users); on != NULL; on = on->next)
{
if (strcasecmp((char *) tmp->data, (char *) on->data) == 0)
break;
}
if (on == NULL)
{
/* not found from list, user's just joined to irc */
gui_notify_join(tmp->data);
ison_users = g_list_append(ison_users, g_strdup(tmp->data));
}
}
/* and then check who's left irc */
for (tmp = g_list_first(ison_users); tmp != NULL; tmp = next)
{
GList *on;
next = tmp->next;
for (on = g_list_first(ison_tempusers); on != NULL; on = on->next)
{
if (strcasecmp((char *) tmp->data, (char *) on->data) == 0)
break;
}
if (on == NULL)
{
/* not found from list, user's left irc */
gui_notify_part(tmp->data);
g_free(tmp->data);
ison_users = g_list_remove_link(ison_users, tmp);
}
}
/* free memory used by temp list */
for (tmp = g_list_first(ison_tempusers); tmp != NULL; tmp = tmp->next)
g_free(tmp->data);
g_list_free(ison_tempusers); ison_tempusers = NULL;
}
}
static void cannot_join(char *channel, char *reason)
{
CHAN_REC *chan;
g_return_if_fail(channel != NULL);
chan = channel_joined(eserver, channel);
drawtext(edefwin, TXT_TYPE_SERVER_TEXT, IRCTXT_CANNOT_JOIN, channel, reason);
if (chan == NULL) return;
if (chan == chan->window->curchan)
irc_select_new_channel(chan->window);
gui_channel_part(chan, NULL);
irc_chan_free(chan);
}
void eirc_nick_unavailable(char *data)
{
g_return_if_fail(data != NULL);
/* skip target list.. */
while (*data != ' ') data++;
data++;
if (*data == '#' || *data == '&')
{
/* channel is unavailable. */
char *channel;
channel = event_get_param(&data);
cannot_join(data, _("Channel is temporarily unavailable"));
return;
}
/* nick is unavailable.. */
eirc_nick_in_use(data);
}
void eirc_too_many_channels(char *data)
{
char *channel;
g_return_if_fail(data != NULL);
event_get_params(data, 2, NULL, &channel);
cannot_join(channel, _("You have joined too many channels"));
}
void eirc_channel_is_full(char *data)
{
char *channel;
g_return_if_fail(data != NULL);
event_get_params(data, 2, NULL, &channel);
cannot_join(channel, _("Channel is full"));
}
void eirc_invite_only(char *data)
{
char *channel;
g_return_if_fail(data != NULL);
event_get_params(data, 2, NULL, &channel);
cannot_join(channel, _("You must be invited"));
}
void eirc_banned(char *data)
{
char *channel;
g_return_if_fail(data != NULL);
event_get_params(data, 2, NULL, &channel);
cannot_join(channel, _("You are banned"));
}
void eirc_bad_channel_key(char *data)
{
char *channel;
g_return_if_fail(data != NULL);
event_get_params(data, 2, NULL, &channel);
cannot_join(channel, _("Bad channel key"));
}
void eirc_bad_channel_mask(char *data)
{
char *channel;
g_return_if_fail(data != NULL);
event_get_params(data, 2, NULL, &channel);
cannot_join(channel, _("Bad channel mask"));
}