1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-07 18:23:13 +02:00

First CVS upload.

This commit is contained in:
Sebastien Helleu
2003-09-27 10:01:11 +00:00
commit 109101faeb
108 changed files with 22604 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
# Copyright (c) 2003 FlashCode <flashcode@flashtux.org>
#
# 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
#
CC=gcc
OPTIONS=-Wall -W -pipe -O2
OUTPUT=irc.a
OBJS=irc-commands.o irc-display.o irc-server.o irc-channel.o irc-nick.o
DEFINES=WEE_CURSES
all: $(OBJS)
ar r $(OUTPUT) $(OBJS)
$(OBJS):
$(CC) $(OPTIONS) -o $@ -c $< $(INCLUDES) -D$(DEFINES)
clean:
rm -f *.o *.a *~ core
irc-channel.o: irc-channel.c ../weechat.h irc.h ../gui/gui.h \
../completion.h ../history.h
irc-commands.o: irc-commands.c ../weechat.h irc.h ../gui/gui.h \
../completion.h ../history.h ../command.h ../irc/irc.h ../config.h
irc-display.o: irc-display.c ../weechat.h irc.h ../gui/gui.h \
../completion.h ../history.h
irc-nick.o: irc-nick.c ../weechat.h irc.h ../gui/gui.h ../completion.h \
../history.h
irc-server.o: irc-server.c ../weechat.h irc.h ../gui/gui.h \
../completion.h ../history.h
+153
View File
@@ -0,0 +1,153 @@
/*
* Copyright (c) 2003 by FlashCode <flashcode@flashtux.org>
* Bounga <bounga@altern.org>
* Xahlexx <xahlexx@tuxisland.org>
* See README for License detail.
*
* 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
*/
/* irc-channel.c: manages a chat (channel or private chat) */
#include <stdlib.h>
#include <string.h>
#include "../weechat.h"
#include "irc.h"
t_irc_channel *current_channel = NULL;
/*
* channel_new: allocate a new channel for a server and add it to the server queue
*/
t_irc_channel *
channel_new (t_irc_server *server, int channel_type, char *channel_name)
{
t_irc_channel *new_channel;
#if DEBUG >= 1
log_printf ("joining channel %s\n", channel_name);
#endif
/* alloc memory for new channel */
if ((new_channel = (t_irc_channel *) malloc (sizeof (t_irc_channel))) == NULL)
{
fprintf (stderr, _("%s cannot allocate new channel"), WEECHAT_ERROR);
return NULL;
}
/* initialize new channel */
new_channel->type = channel_type;
new_channel->name = strdup (channel_name);
new_channel->topic = NULL;
new_channel->nicks = NULL;
new_channel->last_nick = NULL;
/* add new channel to queue */
new_channel->prev_channel = server->last_channel;
new_channel->next_channel = NULL;
if (server->channels)
server->last_channel->next_channel = new_channel;
else
server->channels = new_channel;
server->last_channel = new_channel;
gui_window_new (server, new_channel);
/* all is ok, return address of new channel */
return new_channel;
}
/*
* channel_free: free a channel and remove it from channels queue
*/
void
channel_free (t_irc_server *server, t_irc_channel *channel)
{
t_irc_channel *new_channels;
/* remove channel from queue */
if (server->last_channel == channel)
server->last_channel = channel->prev_channel;
if (channel->prev_channel)
{
(channel->prev_channel)->next_channel = channel->next_channel;
new_channels = server->channels;
}
else
new_channels = channel->next_channel;
if (channel->next_channel)
(channel->next_channel)->prev_channel = channel->prev_channel;
/* free data */
if (channel->name)
free (channel->name);
if (channel->topic)
free (channel->topic);
nick_free_all (channel);
free (channel);
server->channels = new_channels;
}
/*
* channel_free_all: free all allocated channels
*/
void
channel_free_all (t_irc_server *server)
{
/* remove all channels for the server */
while (server->channels)
channel_free (server, server->channels);
}
/*
* channel_search: returns pointer on a channel with name
*/
t_irc_channel *
channel_search (t_irc_server *server, char *channel_name)
{
t_irc_channel *ptr_channel;
for (ptr_channel = server->channels; ptr_channel;
ptr_channel = ptr_channel->next_channel)
{
if (strcasecmp (ptr_channel->name, channel_name) == 0)
return ptr_channel;
}
return NULL;
}
/*
* string_is_channel: returns 1 if string is channel
*/
int
string_is_channel (char *string)
{
char first_char[2];
first_char[0] = string[0];
first_char[1] = '\0';
return (strpbrk (first_char, CHANNEL_PREFIX)) ? 1 : 0;
}
File diff suppressed because it is too large Load Diff
+127
View File
@@ -0,0 +1,127 @@
/*
* Copyright (c) 2003 by FlashCode <flashcode@flashtux.org>
* Bounga <bounga@altern.org>
* Xahlexx <xahlexx@tuxisland.org>
* See README for License detail.
*
* 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
*/
/* irc-display.c: display functions for IRC */
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "../weechat.h"
#include "irc.h"
#include "../config.h"
#include "../gui/gui.h"
/*
* irc_display_prefix: display prefix for action or info message
* prefix must be 3 chars length
*/
void
irc_display_prefix (t_gui_window *window, char *prefix)
{
if (prefix[0] == prefix[2])
{
gui_printf_color (window, COLOR_WIN_CHAT_PREFIX1, "%c", prefix[0]);
gui_printf_color (window, COLOR_WIN_CHAT_PREFIX2, "%c", prefix[1]);
gui_printf_color (window, COLOR_WIN_CHAT_PREFIX1, "%c ", prefix[2]);
}
else
gui_printf_color (window, COLOR_WIN_CHAT_PREFIX1, "%s ", prefix);
}
/*
* irc_display_nick: display nick in chat window
*/
void
irc_display_nick (t_gui_window *window, t_irc_nick *nick, int message_type,
int display_around, int color_nick, int no_nickmode)
{
if (display_around)
gui_printf_color_type (window,
message_type, COLOR_WIN_CHAT_DARK, "<");
if (cfg_look_nickmode)
{
if (nick->is_op)
gui_printf_color_type (window,
message_type,
COLOR_WIN_NICK_OP, "@");
else
{
if (nick->is_halfop)
gui_printf_color_type (window,
message_type,
COLOR_WIN_NICK_HALFOP, "%%");
else
{
if (nick->has_voice)
gui_printf_color_type (window,
message_type,
COLOR_WIN_NICK_VOICE, "+");
else
if (cfg_look_nickmode_empty && !no_nickmode)
gui_printf_color_type (window,
message_type,
COLOR_WIN_CHAT, " ");
}
}
}
gui_printf_color_type (window,
message_type,
(color_nick) ?
((cfg_look_color_nicks) ?
nick->color : COLOR_WIN_CHAT) :
COLOR_WIN_CHAT,
"%s", nick->nick);
if (display_around)
gui_printf_color_type (window,
message_type, COLOR_WIN_CHAT_DARK, "> ");
}
/*
* irc_display_mode: display IRC message for mode change
*/
void
irc_display_mode (t_gui_window *window, char *channel_name, char set_flag,
char *symbol, char *nick_host, char *message, char *param)
{
irc_display_prefix (window, PREFIX_INFO);
gui_printf_color (window, COLOR_WIN_CHAT_DARK, "[");
gui_printf_color (window, COLOR_WIN_CHAT_CHANNEL, "%s", channel_name);
gui_printf_color (window, COLOR_WIN_CHAT, "/");
gui_printf_color (window, COLOR_WIN_CHAT_CHANNEL, "%c%s", set_flag, symbol);
gui_printf_color (window, COLOR_WIN_CHAT_DARK, "] ");
gui_printf_color (window, COLOR_WIN_CHAT_NICK, "%s", nick_host);
if (param)
{
gui_printf_color (window, COLOR_WIN_CHAT, " %s ", message);
gui_printf_color (window, COLOR_WIN_CHAT_NICK, "%s\n", param);
}
else
gui_printf_color (window, COLOR_WIN_CHAT, " %s\n", message);
}
+357
View File
@@ -0,0 +1,357 @@
/*
* Copyright (c) 2003 by FlashCode <flashcode@flashtux.org>
* Bounga <bounga@altern.org>
* Xahlexx <xahlexx@tuxisland.org>
* See README for License detail.
*
* 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
*/
/* irc-nick.c: manages nick list for channels */
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "../weechat.h"
#include "irc.h"
/*
* nick_find_color: find a color for a nick (less used will be better!)
*/
int
nick_find_color (t_irc_channel *channel)
{
int i, color_less_used, min_used;
int count_used[COLOR_WIN_NICK_NUMBER];
t_irc_nick *ptr_nick;
/* initialize array for counting usage of color */
for (i = 0; i < COLOR_WIN_NICK_NUMBER; i++)
count_used[i] = 0;
/* summarize each color usage */
for (ptr_nick = channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick)
count_used[ptr_nick->color - COLOR_WIN_NICK_FIRST]++;
/* look for color less used on channel */
color_less_used = -1;
min_used = INT_MAX;
for (i = 0; i < COLOR_WIN_NICK_NUMBER; i++)
{
if (count_used[i] < min_used)
{
color_less_used = i;
min_used = count_used[i];
}
}
return (color_less_used < 0) ?
COLOR_WIN_NICK_FIRST : COLOR_WIN_NICK_FIRST + color_less_used;
}
/*
* nick_compare: compare two nicks
* return: -1 is nick1 < nick2
* 0 if nick1 = nick2
* +1 if nick1 > nick2
* status sort: operator > voice > normal nick
*/
int
nick_compare (t_irc_nick *nick1, t_irc_nick *nick2)
{
int score1, score2, comp;
score1 = - ( (nick1->is_op * 3) + (nick1->is_halfop * 2) + nick1->has_voice );
score2 = - ( (nick2->is_op * 3) + (nick2->is_halfop * 2) + nick2->has_voice );
comp = strcasecmp(nick1->nick, nick2->nick);
if (comp > 0)
score1++;
else
if (comp < 0)
score2++;
/* nick1 > nick2 */
if (score1 > score2)
return 1;
/* nick1 < nick2 */
if (score1 < score2)
return -1;
/* nick1 == nick2 */
return 0;
}
/*
* nick_find_pos: find position for a nick (for sorting nick list)
*/
t_irc_nick *
nick_find_pos (t_irc_channel *channel, t_irc_nick *nick)
{
t_irc_nick *ptr_nick;
for (ptr_nick = channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick)
{
if (nick_compare (nick, ptr_nick) < 0)
return ptr_nick;
}
return NULL;
}
/*
* nick_insert_sorted: insert nick into sorted list
*/
void
nick_insert_sorted (t_irc_channel *channel, t_irc_nick *nick)
{
t_irc_nick *pos_nick;
if (channel->nicks)
{
pos_nick = nick_find_pos (channel, nick);
if (pos_nick)
{
/* insert nick into the list (before nick found) */
nick->prev_nick = pos_nick->prev_nick;
nick->next_nick = pos_nick;
if (pos_nick->prev_nick)
pos_nick->prev_nick->next_nick = nick;
else
channel->nicks = nick;
pos_nick->prev_nick = nick;
}
else
{
/* add nick to the end */
nick->prev_nick = channel->last_nick;
nick->next_nick = NULL;
channel->last_nick->next_nick = nick;
channel->last_nick = nick;
}
}
else
{
nick->prev_nick = NULL;
nick->next_nick = NULL;
channel->nicks = nick;
channel->last_nick = nick;
}
}
/*
* nick_new: allocate a new nick for a channel and add it to the nick list
*/
t_irc_nick *
nick_new (t_irc_channel *channel, char *nick_name,
int is_op, int is_halfop, int has_voice)
{
t_irc_nick *new_nick;
/* nick already exists on this channel? */
if ((new_nick = nick_search (channel, nick_name)))
{
/* update nick */
new_nick->is_op = is_op;
new_nick->is_halfop = is_halfop;
new_nick->has_voice = has_voice;
return new_nick;
}
/* alloc memory for new nick */
if ((new_nick = (t_irc_nick *) malloc (sizeof (t_irc_nick))) == NULL)
{
gui_printf (channel->window,
_("%s cannot allocate new nick\n"), WEECHAT_ERROR);
return NULL;
}
/* initialize new nick */
new_nick->nick = strdup (nick_name);
new_nick->is_op = is_op;
new_nick->is_halfop = is_halfop;
new_nick->has_voice = has_voice;
if (strcasecmp (new_nick->nick, SERVER(channel->window)->nick) == 0)
new_nick->color = COLOR_WIN_NICK_SELF;
else
new_nick->color = nick_find_color (channel);
nick_insert_sorted (channel, new_nick);
/* all is ok, return address of new nick */
return new_nick;
}
/*
* nick_resort: resort nick in the list
*/
void
nick_resort (t_irc_channel *channel, t_irc_nick *nick)
{
/* temporarly remove nick from list */
if (nick == channel->nicks)
channel->nicks = nick->next_nick;
else
nick->prev_nick->next_nick = nick->next_nick;
if (nick->next_nick)
nick->next_nick->prev_nick = nick->prev_nick;
if (nick == channel->last_nick)
channel->last_nick = nick->prev_nick;
/* insert again nick into sorted list */
nick_insert_sorted (channel, nick);
}
/*
* nick_change: change nickname and move it if necessary (list is sorted)
*/
void
nick_change (t_irc_channel *channel, t_irc_nick *nick, char *new_nick)
{
/* change nickname */
if (nick->nick)
free (nick->nick);
nick->nick = strdup (new_nick);
/* insert again nick into sorted list */
nick_resort (channel, nick);
}
/*
* nick_free: free a nick and remove it from nicks queue
*/
void
nick_free (t_irc_channel *channel, t_irc_nick *nick)
{
t_irc_nick *new_nicks;
/* remove nick from queue */
if (channel->last_nick == nick)
channel->last_nick = nick->prev_nick;
if (nick->prev_nick)
{
(nick->prev_nick)->next_nick = nick->next_nick;
new_nicks = channel->nicks;
}
else
new_nicks = nick->next_nick;
if (nick->next_nick)
(nick->next_nick)->prev_nick = nick->prev_nick;
/* free data */
if (nick->nick)
free (nick->nick);
free (nick);
channel->nicks = new_nicks;
}
/*
* nick_free_all: free all allocated nicks for a channel
*/
void
nick_free_all (t_irc_channel *channel)
{
/* remove all nicks for the channel */
while (channel->nicks)
nick_free (channel, channel->nicks);
}
/*
* nick_search: returns pointer on a nick
*/
t_irc_nick *
nick_search (t_irc_channel *channel, char *nickname)
{
t_irc_nick *ptr_nick;
for (ptr_nick = channel->nicks; ptr_nick;
ptr_nick = ptr_nick->next_nick)
{
if (strcasecmp (ptr_nick->nick, nickname) == 0)
return ptr_nick;
}
return NULL;
}
/*
* nick_count: returns number of nicks (total, op, halfop, voice) on a channel
*/
void
nick_count (t_irc_channel *channel, int *total, int *count_op,
int *count_halfop, int *count_voice, int *count_normal)
{
t_irc_nick *ptr_nick;
(*total) = 0;
(*count_op) = 0;
(*count_halfop) = 0;
(*count_voice) = 0;
(*count_normal) = 0;
for (ptr_nick = channel->nicks; ptr_nick;
ptr_nick = ptr_nick->next_nick)
{
(*total)++;
if (ptr_nick->is_op)
(*count_op)++;
else
{
if (ptr_nick->is_halfop)
(*count_halfop)++;
else
{
if (ptr_nick->has_voice)
(*count_voice)++;
else
(*count_normal)++;
}
}
}
}
/*
* nick_get_max_length: returns longer nickname on a channel
*/
int
nick_get_max_length (t_irc_channel *channel)
{
int length, max_length;
t_irc_nick *ptr_nick;
max_length = 0;
for (ptr_nick = channel->nicks; ptr_nick;
ptr_nick = ptr_nick->next_nick)
{
length = strlen (ptr_nick->nick);
if (length > max_length)
max_length = length;
}
return max_length;
}
+615
View File
@@ -0,0 +1,615 @@
/*
* Copyright (c) 2003 by FlashCode <flashcode@flashtux.org>
* Bounga <bounga@altern.org>
* Xahlexx <xahlexx@tuxisland.org>
* See README for License detail.
*
* 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
*/
/* irc-server.c: (dis)connection and communication with irc server */
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "../weechat.h"
#include "irc.h"
#include "../gui/gui.h"
t_irc_server *irc_servers = NULL;
t_irc_server *last_irc_server = NULL;
t_irc_server *current_irc_server = NULL;
t_irc_message *recv_msgq, *msgq_last_msg;
/* buffer containing beginning of message if not ending with \r\n */
char *unterminated_message = NULL;
/*
* server_alloc: allocate a new server and add it to the servers queue
*/
t_irc_server *
server_alloc ()
{
t_irc_server *new_server;
#if DEBUG >= 1
log_printf ("allocating new server\n");
#endif
/* alloc memory for new server */
if ((new_server = (t_irc_server *) malloc (sizeof (t_irc_server))) == NULL)
{
fprintf (stderr, _("%s cannot allocate new server"), WEECHAT_ERROR);
return NULL;
}
/* initialize new server */
new_server->name = NULL;
new_server->address = NULL;
new_server->password = NULL;
new_server->nick1 = NULL;
new_server->nick2 = NULL;
new_server->nick3 = NULL;
new_server->username = NULL;
new_server->realname = NULL;
new_server->nick = NULL;
new_server->is_connected = 0;
new_server->sock4 = -1;
new_server->is_away = 0;
new_server->server_read = -1;
new_server->server_write = -1;
new_server->window = NULL;
new_server->channels = NULL;
new_server->last_channel = NULL;
/* add new server to queue */
new_server->prev_server = last_irc_server;
new_server->next_server = NULL;
if (irc_servers)
last_irc_server->next_server = new_server;
else
irc_servers = new_server;
last_irc_server = new_server;
/* all is ok, return address of new server */
return new_server;
}
/*
* server_create_window: create windows for a server
*/
void
server_create_window (t_irc_server *server)
{
if (!SERVER(gui_windows))
{
server->window = gui_windows;
SERVER(gui_windows) = server;
}
else
gui_window_new (server, NULL);
}
/*
* server_free: free a server and remove it from servers queue
*/
void
server_free (t_irc_server *server)
{
t_irc_server *new_irc_servers;
/* remove server from queue */
if (server->prev_server)
{
(server->prev_server)->next_server = server->next_server;
new_irc_servers = irc_servers;
}
else
new_irc_servers = server->next_server;
if (server->next_server)
(server->next_server)->prev_server = server->prev_server;
/* free data */
if (server->name)
free (server->name);
if (server->address)
free (server->address);
if (server->password)
free (server->password);
if (server->nick1)
free (server->nick1);
if (server->nick2)
free (server->nick2);
if (server->nick3)
free (server->nick3);
if (server->username)
free (server->username);
if (server->realname)
free (server->realname);
if (server->nick)
free (server->nick);
if (server->channels)
channel_free_all (server);
/* TODO: free weechat window (???) */
/* (...) */
free (server);
irc_servers = new_irc_servers;
}
/*
* server_free_all: free all allocated servers
*/
void
server_free_all ()
{
/* for each server in memory, remove it */
while (irc_servers)
server_free (irc_servers);
}
/*
* server_new: creates a new server, and initialize it
*/
t_irc_server *
server_new (char *name, char *address, int port, char *password,
char *nick1, char *nick2, char *nick3,
char *username, char *realname)
{
t_irc_server *new_server;
if (!name || !address || (port < 0) || !nick1 || !nick2 || !nick3
|| !username || !realname)
return NULL;
#if DEBUG >= 1
log_printf ("creating new server (name:%s, address:%s, port:%d, pwd:%s, "
"nick1:%s, nick2:%s, nick3:%s, username:%s, realname:%s)\n",
name, address, port, password, nick1, nick2, nick3,
username, realname);
#endif
if ((new_server = server_alloc ()))
{
new_server->name = strdup (name);
new_server->address = strdup (address);
new_server->port = port;
new_server->password = (password) ? strdup (password) : strdup ("");
new_server->nick1 = (nick1) ? strdup (nick1) : strdup ("weechat_user");
new_server->nick2 = (nick2) ? strdup (nick2) : strdup ("weechat2");
new_server->nick3 = (nick3) ? strdup (nick3) : strdup ("weechat3");
new_server->username =
(username) ? strdup (username) : strdup ("weechat");
new_server->realname =
(realname) ? strdup (realname) : strdup ("realname");
new_server->nick = strdup (new_server->nick1);
}
else
return NULL;
return new_server;
}
/*
* server_send: send data to irc server
*/
int
server_send (t_irc_server * server, char *buffer, int size_buf)
{
if (!server)
return -1;
return send (server->sock4, buffer, size_buf, 0);
}
/*
* server_sendf: send formatted data to irc server
*/
int
server_sendf (t_irc_server * server, char *fmt, ...)
{
va_list args;
static char buffer[1024];
int size_buf;
if (!server)
return -1;
va_start (args, fmt);
size_buf = vsnprintf (buffer, sizeof (buffer) - 1, fmt, args);
va_end (args);
if ((size_buf == 0) || (strcmp (buffer, "\r\n") == 0))
return 0;
buffer[sizeof (buffer) - 1] = '\0';
if ((size_buf < 0) || (size_buf > (int) (sizeof (buffer) - 1)))
size_buf = strlen (buffer);
buffer[size_buf - 2] = '\0';
#if DEBUG >= 2
gui_printf (server->window, "[DEBUG] Sending to server >>> %s\n", buffer);
#endif
buffer[size_buf - 2] = '\r';
return server_send (server, buffer, size_buf);
}
/*
* server_msgq_add_msg: add a message to received messages queue (at the end)
*/
void
server_msgq_add_msg (t_irc_server * server, char *msg)
{
t_irc_message *message;
message = (t_irc_message *) malloc (sizeof (t_irc_message));
message->server = server;
if (unterminated_message)
{
message->data = (char *) malloc (strlen (unterminated_message) +
strlen (msg) + 1);
strcpy (message->data, unterminated_message);
strcat (message->data, msg);
free (unterminated_message);
unterminated_message = NULL;
}
else
message->data = strdup (msg);
message->next_message = NULL;
if (msgq_last_msg)
{
msgq_last_msg->next_message = message;
msgq_last_msg = message;
}
else
{
recv_msgq = message;
msgq_last_msg = message;
}
}
/*
* server_msgq_add_buffer: explode received buffer, creating queued messages
*/
void
server_msgq_add_buffer (t_irc_server * server, char *buffer)
{
char *pos;
while (buffer[0])
{
pos = strstr (buffer, "\r\n");
if (pos)
{
pos[0] = '\0';
server_msgq_add_msg (server, buffer);
buffer = pos + 2;
}
else
{
pos = strchr (buffer, '\0');
if (pos)
{
unterminated_message =
(char *) realloc (unterminated_message,
strlen (buffer) + 1);
strcpy (unterminated_message, buffer);
return;
}
gui_printf (server->window,
_("%s unable to explode received buffer\n"),
WEECHAT_ERROR);
}
}
}
/*
* server_msgq_flush: flush message queue
*/
void
server_msgq_flush ()
{
t_irc_message *next;
/*char **argv;
int argc;*/
char *ptr_data, *pos, *pos2;
char *host, *command, *args;
/* TODO: optimize this function, parse only a few messages (for low CPU time!) */
while (recv_msgq)
{
#if DEBUG >= 2
gui_printf (gui_current_window, "[DEBUG] %s\n", recv_msgq->data);
#endif
ptr_data = recv_msgq->data;
while (ptr_data[0] == ' ')
ptr_data++;
if (ptr_data)
{
#if DEBUG >= 2
gui_printf (NULL, "[DEBUG] data received from server: %s\n", ptr_data);
#endif
host = NULL;
command = NULL;
args = ptr_data;
if (ptr_data[0] == ':')
{
pos = strchr(ptr_data, ' ');
pos[0] = '\0';
host = ptr_data+1;
pos++;
}
else
pos = ptr_data;
if (pos != NULL)
{
while (pos[0] == ' ')
pos++;
pos2 = strchr(pos, ' ');
if (pos2 != NULL)
{
pos2[0] = '\0';
command = strdup(pos);
pos2++;
while (pos2[0] == ' ')
pos2++;
args = (pos2[0] == ':') ? pos2+1 : pos2;
}
}
switch (irc_recv_command (recv_msgq->server, host, command, args))
{
case -1:
gui_printf (recv_msgq->server->window,
_("Command '%s' failed!\n"), command);
break;
case -2:
gui_printf (recv_msgq->server->window,
_("No command to execute!\n"));
break;
case -3:
gui_printf (recv_msgq->server->window,
_("Unknown command: cmd=%s, args=%s\n"),
command, args);
break;
}
}
free (recv_msgq->data);
next = recv_msgq->next_message;
free (recv_msgq);
recv_msgq = next;
if (recv_msgq == NULL)
msgq_last_msg = NULL;
}
}
/*
* server_recv: receive data from an irc server
*/
void
server_recv (t_irc_server *server)
{
static char buffer[4096 + 2];
int num_read;
num_read = recv (server->sock4, buffer, sizeof (buffer) - 2, 0);
if (num_read > 0)
{
buffer[num_read] = '\0';
server_msgq_add_buffer (server, buffer);
server_msgq_flush ();
}
}
/*
* server_connect: connect to an irc server
*/
int
server_connect (t_irc_server *server)
{
int set;
struct hostent *ip4_hostent;
struct sockaddr_in addr;
char *ip_address;
int error;
int server_pipe[2];
gui_printf (server->window,
_(WEECHAT_NAME ": connecting to %s:%d...\n"),
server->address, server->port);
log_printf ("connecting to server %s:%d...\n",
server->address, server->port);
server->is_connected = 0;
/* create pipe */
if (pipe (server_pipe) < 0)
{
gui_printf (server->window,
_("%s cannot create pipe\n"), WEECHAT_ERROR);
server_free (server);
return 0;
}
server->server_read = server_pipe[0];
server->server_write = server_pipe[1];
/* create socket and set options */
server->sock4 = socket (AF_INET, SOCK_STREAM, 0);
set = 1;
if (setsockopt
(server->sock4, SOL_SOCKET, SO_REUSEADDR, (char *) &set,
sizeof (set)) == -1)
gui_printf (server->window,
_("%s cannot set socket option 'SO_REUSEADDR'\n"),
WEECHAT_ERROR);
set = 1;
if (setsockopt
(server->sock4, SOL_SOCKET, SO_KEEPALIVE, (char *) &set,
sizeof (set)) == -1)
gui_printf (server->window,
_("%s cannot set socket option \"SO_KEEPALIVE\"\n"),
WEECHAT_ERROR);
/* bind to hostname */
ip4_hostent = gethostbyname (server->address);
if (!ip4_hostent)
{
gui_printf (server->window,
_("%s address \"%s\" not found\n"),
WEECHAT_ERROR, server->address);
close (server->server_read);
close (server->server_write);
close (server->sock4);
server->sock4 = -1;
return 0;
}
memset (&addr, 0, sizeof (addr));
memcpy (&addr.sin_addr, ip4_hostent->h_addr, ip4_hostent->h_length);
addr.sin_port = htons (server->port);
addr.sin_family = AF_INET;
/*error = bind(server->sock4, (struct sockaddr *)(&addr), sizeof(addr));
if (error != 0)
{
gui_printf (server->window,
WEECHAT_ERORR "server_connect: can't bind to hostname\n");
return 0;
} */
ip_address = inet_ntoa (addr.sin_addr);
if (!ip_address)
{
gui_printf (server->window,
_("%s IP address not found\n"), WEECHAT_ERROR);
close (server->server_read);
close (server->server_write);
close (server->sock4);
server->sock4 = -1;
return 0;
}
/* connection to server */
gui_printf (server->window,
_(WEECHAT_NAME ": server IP is: %s\n"), ip_address);
error = connect (server->sock4, (struct sockaddr *) &addr, sizeof (addr));
if (error != 0)
{
gui_printf (server->window,
_("%s cannot connect to irc server\n"), WEECHAT_ERROR);
close (server->server_read);
close (server->server_write);
close (server->sock4);
server->sock4 = -1;
return 0;
}
current_irc_server = server;
return 1;
}
/*
* server_disconnect: disconnect from an irc server
*/
void
server_disconnect (t_irc_server *server)
{
if (server->is_connected)
{
close (server->server_read);
close (server->server_write);
close (server->sock4);
server->is_connected = 0;
}
}
/*
* server_disconnect_all: disconnect from all irc servers
*/
void
server_disconnect_all ()
{
t_irc_server *ptr_server;
for (ptr_server = irc_servers; ptr_server; ptr_server = ptr_server->next_server)
server_disconnect (ptr_server);
}
/*
* server_get_number_connected: returns number of connected server
*/
int
server_get_number_connected ()
{
t_irc_server *ptr_server;
int number;
number = 0;
for (ptr_server = irc_servers; ptr_server; ptr_server = ptr_server->next_server)
{
if (ptr_server->is_connected)
number++;
}
return number;
}
/*
* server_name_already_exists: return 1 if server name already exists
* otherwise return 0
*/
int
server_name_already_exists (char *name)
{
t_irc_server *ptr_server;
for (ptr_server = irc_servers; ptr_server; ptr_server = ptr_server->next_server)
{
if (strcmp (ptr_server->name, name) == 0)
return 1;
}
return 0;
}
+247
View File
@@ -0,0 +1,247 @@
/*
* Copyright (c) 2003 by FlashCode <flashcode@flashtux.org>
* Bounga <bounga@altern.org>
* Xahlexx <xahlexx@tuxisland.org>
* See README for License detail.
*
* 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
*/
#ifndef __WEECHAT_IRC_H
#define __WEECHAT_IRC_H 1
#include "../gui/gui.h"
#define PREFIX_SERVER "-@-"
#define PREFIX_INFO "-=-"
#define PREFIX_ACTION_ME "-*-"
#define PREFIX_JOIN "-->"
#define PREFIX_PART "<--"
#define PREFIX_QUIT "<--"
#define PREFIX_ERROR "=!="
#define CHANNEL_PREFIX "#&+!"
/* nick types */
typedef struct t_irc_nick t_irc_nick;
struct t_irc_nick
{
char *nick; /* nickname */
int is_op; /* operator privileges? */
int is_halfop; /* half operaor privileges? */
int has_voice; /* nick has voice? */
int color; /* color for nickname */
t_irc_nick *prev_nick; /* link to previous nick on the channel */
t_irc_nick *next_nick; /* link to next nick on the channel */
};
/* channel types */
typedef struct t_irc_channel t_irc_channel;
#define CHAT_UNKNOWN -1
#define CHAT_CHANNEL 0
#define CHAT_PRIVATE 1
struct t_irc_channel
{
int type; /* channel type */
char *name; /* name of channel (exemple: "#abc") */
char *topic; /* topic of channel (host for private) */
t_irc_nick *nicks; /* nicks on the channel */
t_irc_nick *last_nick; /* last nick on the channel */
t_gui_window *window; /* GUI window allocated for channel */
t_irc_channel *prev_channel; /* link to previous channel */
t_irc_channel *next_channel; /* link to next channel */
};
/* server types */
typedef struct t_irc_server t_irc_server;
struct t_irc_server
{
/* user choices */
char *name; /* name of server (only for display) */
char *address; /* address of server (IP or name) */
int port; /* port for server (6667 by default) */
char *password; /* password for server */
char *nick1; /* first nickname for the server */
char *nick2; /* alternate nickname */
char *nick3; /* 2nd alternate nickname */
char *username; /* user name */
char *realname; /* real name */
/* internal vars */
char *nick; /* current nickname */
int is_connected; /* 1 if WeeChat is connected to server */
int sock4; /* socket for server */
int is_away; /* 1 is user is marker as away */
int server_read; /* pipe for reading server data */
int server_write; /* pipe for sending data to server */
t_gui_window *window; /* GUI window allocated for server */
t_irc_channel *channels; /* opened channels on server */
t_irc_channel *last_channel; /* last opened channal on server */
t_irc_server *prev_server; /* link to previous server */
t_irc_server *next_server; /* link to next server */
};
/* irc commands */
typedef struct t_irc_command t_irc_command;
struct t_irc_command
{
char *command_name; /* command name (internal or IRC cmd) */
char *command_description; /* command description */
char *arguments; /* command parameters */
char *arguments_description; /* parameters description */
int min_arg, max_arg; /* min & max number of parameters */
int need_connection; /* = 1 if cmd needs server connection */
int (*cmd_function_args)(t_irc_server *, int, char **);
/* function called when user enters cmd */
int (*cmd_function_1arg)(t_irc_server *, char *);
/* function called when user enters cmd */
int (*recv_function)(t_irc_server *, char *, char *);
/* function called when cmd is received */
};
typedef struct t_irc_message t_irc_message;
struct t_irc_message
{
t_irc_server *server; /* server pointer for received msg */
char *data; /* message content */
t_irc_message *next_message; /* link to next message */
};
extern t_irc_command irc_commands[];
extern t_irc_server *irc_servers, *current_irc_server;
extern t_irc_message *recv_msgq, *msgq_last_msg;
extern t_irc_channel *current_channel;
/* server functions (irc-server.c) */
extern t_irc_server *server_alloc ();
extern void server_create_window (t_irc_server *);
extern void server_free (t_irc_server *);
extern void server_free_all ();
extern t_irc_server *server_new (char *, char *, int, char *, char *, char *,
char *, char *, char *);
extern int server_send (t_irc_server *, char *, int);
extern int server_sendf (t_irc_server *, char *, ...);
extern void server_recv (t_irc_server *);
extern int server_connect ();
extern void server_disconnect (t_irc_server *);
extern void server_disconnect_all ();
extern int server_get_number_connected ();
extern int server_name_already_exists (char *);
/* channel functions (irc-channel.c) */
extern t_irc_channel *channel_new (t_irc_server *, int, char *);
extern void channel_free (t_irc_server *, t_irc_channel *);
extern void channel_free_all (t_irc_server *);
extern t_irc_channel *channel_search (t_irc_server *, char *);
extern int string_is_channel (char *);
/* nick functions (irc-nick.c) */
extern t_irc_nick *nick_new (t_irc_channel *, char *, int, int, int);
extern void nick_resort (t_irc_channel *, t_irc_nick *);
extern void nick_change (t_irc_channel *, t_irc_nick *, char *);
extern void nick_free (t_irc_channel *, t_irc_nick *);
extern void nick_free_all (t_irc_channel *);
extern t_irc_nick *nick_search (t_irc_channel *, char *);
extern void nick_count (t_irc_channel *, int *, int *, int *, int *, int *);
extern int nick_get_max_length (t_irc_channel *);
/* IRC display (irc-diplay.c) */
extern void irc_display_prefix (t_gui_window *, char *);
extern void irc_display_nick (t_gui_window *, t_irc_nick *, int, int, int, int);
extern void irc_display_mode (t_gui_window *, char *, char, char *, char *,
char *, char *);
/* IRC protocol (irc-commands.c) */
extern int irc_recv_command (t_irc_server *, char *, char *, char *);
extern void irc_login (t_irc_server *);
/* IRC commands issued by user */
extern int irc_cmd_send_away (t_irc_server *, char *);
extern int irc_cmd_send_ctcp (t_irc_server *, char *);
extern int irc_cmd_send_deop (t_irc_server *, int, char **);
extern int irc_cmd_send_devoice (t_irc_server *, int, char **);
extern int irc_cmd_send_invite (t_irc_server *, char *);
extern int irc_cmd_send_join (t_irc_server *, char *);
extern int irc_cmd_send_kick (t_irc_server *, char *);
extern int irc_cmd_send_kill (t_irc_server *, char *);
extern int irc_cmd_send_list (t_irc_server *, char *);
extern int irc_cmd_send_me (t_irc_server *, char *);
extern int irc_cmd_send_mode (t_irc_server *, char *);
extern int irc_cmd_send_msg (t_irc_server *, char *);
extern int irc_cmd_send_names (t_irc_server *, char *);
extern int irc_cmd_send_nick (t_irc_server *, int, char **);
extern int irc_cmd_send_notice (t_irc_server *, char *);
extern int irc_cmd_send_op (t_irc_server *, int, char **);
extern int irc_cmd_send_oper (t_irc_server *, int, char **);
extern int irc_cmd_send_part (t_irc_server *, char *);
extern int irc_cmd_send_ping (t_irc_server *, int, char **);
extern int irc_cmd_send_pong (t_irc_server *, int, char **);
extern int irc_cmd_send_quit (t_irc_server *, char *);
extern int irc_cmd_send_quote (t_irc_server *, char *);
extern int irc_cmd_send_topic (t_irc_server *, char *);
extern int irc_cmd_send_version (t_irc_server *, char *);
extern int irc_cmd_send_voice (t_irc_server *, int, char **);
extern int irc_cmd_send_whois (t_irc_server *, char *);
/* IRC commands executed when received from server */
extern int irc_cmd_recv_error (t_irc_server *, char *, char *);
extern int irc_cmd_recv_join (t_irc_server *, char *, char *);
extern int irc_cmd_recv_kick (t_irc_server *, char *, char *);
extern int irc_cmd_recv_mode (t_irc_server *, char *, char *);
extern int irc_cmd_recv_nick (t_irc_server *, char *, char *);
extern int irc_cmd_recv_notice (t_irc_server *, char *, char *);
extern int irc_cmd_recv_part (t_irc_server *, char *, char *);
extern int irc_cmd_recv_ping (t_irc_server *, char *, char *);
extern int irc_cmd_recv_privmsg (t_irc_server *, char *, char *);
extern int irc_cmd_recv_quit (t_irc_server *, char *, char *);
extern int irc_cmd_recv_server_msg (t_irc_server *, char *, char *);
extern int irc_cmd_recv_server_reply (t_irc_server *, char *, char *);
extern int irc_cmd_recv_topic (t_irc_server *, char *, char *);
extern int irc_cmd_recv_001 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_004 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_301 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_311 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_312 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_313 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_317 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_318 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_319 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_320 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_321 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_322 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_323 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_331 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_332 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_333 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_351 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_353 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_366 (t_irc_server *, char *, char *);
extern int irc_cmd_recv_433 (t_irc_server *, char *, char *);
#endif /* irc.h */