mirror of
https://github.com/glest/glest-source.git
synced 2025-09-26 23:49:03 +02:00
- build fix for poor distros who have a hard time with libircclient (now we just include this small lib in the source tree) so no longer required as an external lib
This commit is contained in:
39
source/shared_lib/sources/libircclient/src/Makefile.in
Normal file
39
source/shared_lib/sources/libircclient/src/Makefile.in
Normal file
@@ -0,0 +1,39 @@
|
||||
# $Id: Makefile.in 84 2009-01-10 01:37:29Z chromerium $
|
||||
CC = @CC@
|
||||
CFLAGS = -Wall -DIN_BUILDING_LIBIRC @CFLAGS@
|
||||
AR=@AR@ cr
|
||||
RANLIB=@RANLIB@
|
||||
INCLUDES=-I../include
|
||||
DESTDIR=
|
||||
|
||||
|
||||
OBJS = libircclient.o
|
||||
|
||||
all: lib
|
||||
|
||||
lib: libircclient.a
|
||||
|
||||
install: lib
|
||||
-mkdir -p $(DESTDIR)@prefix@/include
|
||||
-mkdir -p $(DESTDIR)@prefix@/lib
|
||||
cp ../include/libircclient.h $(DESTDIR)@prefix@/include/libircclient.h
|
||||
cp ../include/libirc_errors.h $(DESTDIR)@prefix@/include/libirc_errors.h
|
||||
cp ../include/libirc_events.h $(DESTDIR)@prefix@/include/libirc_events.h
|
||||
cp libircclient.a $(DESTDIR)@prefix@/lib/libircclient.a
|
||||
cd $(DESTDIR)@prefix@/lib && ln -s libircclient.a libirc.a
|
||||
|
||||
$(OBJS): utils.c dcc.c errors.c portable.c sockets.c colors.c
|
||||
|
||||
libircclient.a: $(OBJS)
|
||||
$(AR) libircclient.a $(OBJS)
|
||||
$(RANLIB) libircclient.a
|
||||
|
||||
clean:
|
||||
rm -f libircclient.a $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
-rm -f Makefile
|
||||
|
||||
.c.o:
|
||||
@echo "Compiling $<"
|
||||
@$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
390
source/shared_lib/sources/libircclient/src/colors.c
Normal file
390
source/shared_lib/sources/libircclient/src/colors.c
Normal file
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2009 Georgy Yunaev gyunaev@ulduzsoft.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public
|
||||
* License for more details.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#define LIBIRC_COLORPARSER_BOLD (1<<1)
|
||||
#define LIBIRC_COLORPARSER_UNDERLINE (1<<2)
|
||||
#define LIBIRC_COLORPARSER_REVERSE (1<<3)
|
||||
#define LIBIRC_COLORPARSER_COLOR (1<<4)
|
||||
|
||||
#define LIBIRC_COLORPARSER_MAXCOLORS 15
|
||||
|
||||
|
||||
static const char * color_replacement_table[] =
|
||||
{
|
||||
"WHITE",
|
||||
"BLACK",
|
||||
"DARKBLUE",
|
||||
"DARKGREEN",
|
||||
"RED",
|
||||
"BROWN",
|
||||
"PURPLE",
|
||||
"OLIVE",
|
||||
"YELLOW",
|
||||
"GREEN",
|
||||
"TEAL",
|
||||
"CYAN",
|
||||
"BLUE",
|
||||
"MAGENTA",
|
||||
"DARKGRAY",
|
||||
"LIGHTGRAY",
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static inline void libirc_colorparser_addorcat (char ** destline, unsigned int * destlen, const char * str)
|
||||
{
|
||||
unsigned int len = strlen(str);
|
||||
|
||||
if ( *destline )
|
||||
{
|
||||
strcpy (*destline, str);
|
||||
*destline += len;
|
||||
}
|
||||
else
|
||||
*destlen += len;
|
||||
}
|
||||
|
||||
|
||||
static void libirc_colorparser_applymask (unsigned int * mask,
|
||||
char ** destline, unsigned int * destlen,
|
||||
unsigned int bitmask, const char * start, const char * end)
|
||||
{
|
||||
if ( (*mask & bitmask) != 0 )
|
||||
{
|
||||
*mask &= ~bitmask;
|
||||
libirc_colorparser_addorcat (destline, destlen, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
*mask |= bitmask;
|
||||
libirc_colorparser_addorcat (destline, destlen, start);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void libirc_colorparser_applycolor (unsigned int * mask,
|
||||
char ** destline, unsigned int * destlen,
|
||||
unsigned int colorid, unsigned int bgcolorid)
|
||||
{
|
||||
const char * end = "[/COLOR]";
|
||||
char startbuf[64];
|
||||
|
||||
if ( bgcolorid != 0 )
|
||||
sprintf (startbuf, "[COLOR=%s/%s]", color_replacement_table[colorid], color_replacement_table[bgcolorid]);
|
||||
else
|
||||
sprintf (startbuf, "[COLOR=%s]", color_replacement_table[colorid]);
|
||||
|
||||
if ( (*mask & LIBIRC_COLORPARSER_COLOR) != 0 )
|
||||
libirc_colorparser_addorcat (destline, destlen, end);
|
||||
|
||||
*mask |= LIBIRC_COLORPARSER_COLOR;
|
||||
libirc_colorparser_addorcat (destline, destlen, startbuf);
|
||||
}
|
||||
|
||||
|
||||
static void libirc_colorparser_closetags (unsigned int * mask,
|
||||
char ** destline, unsigned int * destlen)
|
||||
{
|
||||
if ( *mask & LIBIRC_COLORPARSER_BOLD )
|
||||
libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_BOLD, 0, "[/B]");
|
||||
|
||||
if ( *mask & LIBIRC_COLORPARSER_UNDERLINE )
|
||||
libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_UNDERLINE, 0, "[/U]");
|
||||
|
||||
if ( *mask & LIBIRC_COLORPARSER_REVERSE )
|
||||
libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_REVERSE, 0, "[/I]");
|
||||
|
||||
if ( *mask & LIBIRC_COLORPARSER_COLOR )
|
||||
libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_COLOR, 0, "[/COLOR]");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* IRC to [code] color conversion. Or strip.
|
||||
*/
|
||||
static char * libirc_colorparser_irc2code (const char * source, int strip)
|
||||
{
|
||||
unsigned int mask = 0, destlen = 0;
|
||||
char * destline = 0, *d = 0;
|
||||
const char *p;
|
||||
int current_color = 1, current_bg = 0;
|
||||
|
||||
/*
|
||||
* There will be two passes. First pass calculates the total length of
|
||||
* the destination string. The second pass allocates memory for the string,
|
||||
* and fills it.
|
||||
*/
|
||||
while ( destline == 0 ) // destline will be set after the 2nd pass
|
||||
{
|
||||
if ( destlen > 0 )
|
||||
{
|
||||
// This is the 2nd pass; allocate memory.
|
||||
if ( (destline = malloc (destlen)) == 0 )
|
||||
return 0;
|
||||
|
||||
d = destline;
|
||||
}
|
||||
|
||||
for ( p = source; *p; p++ )
|
||||
{
|
||||
switch (*p)
|
||||
{
|
||||
case 0x02: // bold
|
||||
if ( strip )
|
||||
continue;
|
||||
|
||||
libirc_colorparser_applymask (&mask, &d, &destlen, LIBIRC_COLORPARSER_BOLD, "[B]", "[/B]");
|
||||
break;
|
||||
|
||||
case 0x1F: // underline
|
||||
if ( strip )
|
||||
continue;
|
||||
|
||||
libirc_colorparser_applymask (&mask, &d, &destlen, LIBIRC_COLORPARSER_UNDERLINE, "[U]", "[/U]");
|
||||
break;
|
||||
|
||||
case 0x16: // reverse
|
||||
if ( strip )
|
||||
continue;
|
||||
|
||||
libirc_colorparser_applymask (&mask, &d, &destlen, LIBIRC_COLORPARSER_REVERSE, "[I]", "[/I]");
|
||||
break;
|
||||
|
||||
case 0x0F: // reset colors
|
||||
if ( strip )
|
||||
continue;
|
||||
|
||||
libirc_colorparser_closetags (&mask, &d, &destlen);
|
||||
break;
|
||||
|
||||
case 0x03: // set color
|
||||
if ( isdigit (p[1]) )
|
||||
{
|
||||
// Parse
|
||||
int bgcolor = -1, color = p[1] - 0x30;
|
||||
p++;
|
||||
|
||||
if ( isdigit (p[1]) )
|
||||
{
|
||||
color = color * 10 + (p[1] - 0x30);
|
||||
p++;
|
||||
}
|
||||
|
||||
// If there is a comma, search for the following
|
||||
// background color
|
||||
if ( p[1] == ',' && isdigit (p[2]) )
|
||||
{
|
||||
bgcolor = p[2] - 0x30;
|
||||
p += 2;
|
||||
|
||||
if ( isdigit (p[1]) )
|
||||
{
|
||||
bgcolor = bgcolor * 10 + (p[1] - 0x30);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for range
|
||||
if ( color <= LIBIRC_COLORPARSER_MAXCOLORS
|
||||
&& bgcolor <= LIBIRC_COLORPARSER_MAXCOLORS )
|
||||
{
|
||||
if ( strip )
|
||||
continue;
|
||||
|
||||
current_color = color;
|
||||
|
||||
if ( bgcolor != -1 )
|
||||
current_bg = bgcolor;
|
||||
|
||||
libirc_colorparser_applycolor (&mask, &d, &destlen, color, current_bg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( destline )
|
||||
*d++ = *p;
|
||||
else
|
||||
destlen++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Close all the opened tags
|
||||
libirc_colorparser_closetags (&mask, &d, &destlen);
|
||||
destlen++; // for 0-terminator
|
||||
}
|
||||
|
||||
*d = '\0';
|
||||
return destline;
|
||||
}
|
||||
|
||||
|
||||
static int libirc_colorparser_colorlookup (const char * color)
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; color_replacement_table[i]; i++ )
|
||||
if ( !strcmp (color, color_replacement_table[i]) )
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* [code] to IRC color conversion.
|
||||
*/
|
||||
char * irc_color_convert_to_mirc (const char * source)
|
||||
{
|
||||
unsigned int destlen = 0;
|
||||
char * destline = 0, *d = 0;
|
||||
const char *p1, *p2, *cur;
|
||||
|
||||
/*
|
||||
* There will be two passes. First pass calculates the total length of
|
||||
* the destination string. The second pass allocates memory for the string,
|
||||
* and fills it.
|
||||
*/
|
||||
while ( destline == 0 ) // destline will be set after the 2nd pass
|
||||
{
|
||||
if ( destlen > 0 )
|
||||
{
|
||||
// This is the 2nd pass; allocate memory.
|
||||
if ( (destline = malloc (destlen)) == 0 )
|
||||
return 0;
|
||||
|
||||
d = destline;
|
||||
}
|
||||
|
||||
cur = source;
|
||||
while ( (p1 = strchr (cur, '[')) != 0 )
|
||||
{
|
||||
const char * replacedval = 0;
|
||||
p2 = 0;
|
||||
|
||||
// Check if the closing bracket is available after p1
|
||||
// and the tag length is suitable
|
||||
if ( p1[1] != '\0'
|
||||
&& (p2 = strchr (p1, ']')) != 0
|
||||
&& (p2 - p1) > 1
|
||||
&& (p2 - p1) < 31 )
|
||||
{
|
||||
// Get the tag
|
||||
char tagbuf[32];
|
||||
int taglen = p2 - p1 - 1;
|
||||
|
||||
memcpy (tagbuf, p1 + 1, taglen);
|
||||
tagbuf[taglen] = '\0';
|
||||
|
||||
if ( !strcmp (tagbuf, "/COLOR") )
|
||||
replacedval = "\x0F";
|
||||
else if ( strstr (tagbuf, "COLOR=") == tagbuf )
|
||||
{
|
||||
int color, bgcolor = -2;
|
||||
char * bcol;
|
||||
|
||||
bcol = strchr (tagbuf + 6, '/');
|
||||
|
||||
if ( bcol )
|
||||
{
|
||||
*bcol++ = '\0';
|
||||
bgcolor = libirc_colorparser_colorlookup (bcol);
|
||||
}
|
||||
|
||||
color = libirc_colorparser_colorlookup (tagbuf + 6);
|
||||
|
||||
if ( color != -1 && bgcolor == -2 )
|
||||
{
|
||||
sprintf (tagbuf, "\x03%02d", color);
|
||||
replacedval = tagbuf;
|
||||
}
|
||||
else if ( color != -1 && bgcolor >= 0 )
|
||||
{
|
||||
sprintf (tagbuf, "\x03%02d,%02d", color, bgcolor);
|
||||
replacedval = tagbuf;
|
||||
}
|
||||
}
|
||||
else if ( !strcmp (tagbuf, "B") || !strcmp (tagbuf, "/B") )
|
||||
replacedval = "\x02";
|
||||
else if ( !strcmp (tagbuf, "U") || !strcmp (tagbuf, "/U") )
|
||||
replacedval = "\x1F";
|
||||
else if ( !strcmp (tagbuf, "I") || !strcmp (tagbuf, "/I") )
|
||||
replacedval = "\x16";
|
||||
}
|
||||
|
||||
if ( replacedval )
|
||||
{
|
||||
// add a part before the tag
|
||||
int partlen = p1 - cur;
|
||||
|
||||
if ( destline )
|
||||
{
|
||||
memcpy (d, cur, partlen);
|
||||
d += partlen;
|
||||
}
|
||||
else
|
||||
destlen += partlen;
|
||||
|
||||
// Add the replacement
|
||||
libirc_colorparser_addorcat (&d, &destlen, replacedval);
|
||||
|
||||
// And move the pointer
|
||||
cur = p2 + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add a whole part before the end tag
|
||||
int partlen;
|
||||
|
||||
if ( !p2 )
|
||||
p2 = cur + strlen(cur);
|
||||
|
||||
partlen = p2 - cur + 1;
|
||||
|
||||
if ( destline )
|
||||
{
|
||||
memcpy (d, cur, partlen);
|
||||
d += partlen;
|
||||
}
|
||||
else
|
||||
destlen += partlen;
|
||||
|
||||
// And move the pointer
|
||||
cur = p2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the rest of string
|
||||
libirc_colorparser_addorcat (&d, &destlen, cur);
|
||||
destlen++; // for 0-terminator
|
||||
}
|
||||
|
||||
*d = '\0';
|
||||
return destline;
|
||||
}
|
||||
|
||||
|
||||
char * irc_color_strip_from_mirc (const char * message)
|
||||
{
|
||||
return libirc_colorparser_irc2code (message, 1);
|
||||
}
|
||||
|
||||
|
||||
char * irc_color_convert_from_mirc (const char * message)
|
||||
{
|
||||
return libirc_colorparser_irc2code (message, 0);
|
||||
}
|
869
source/shared_lib/sources/libircclient/src/dcc.c
Normal file
869
source/shared_lib/sources/libircclient/src/dcc.c
Normal file
@@ -0,0 +1,869 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2009 Georgy Yunaev gyunaev@ulduzsoft.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public
|
||||
* License for more details.
|
||||
*/
|
||||
|
||||
#define LIBIRC_DCC_CHAT 1
|
||||
#define LIBIRC_DCC_SENDFILE 2
|
||||
#define LIBIRC_DCC_RECVFILE 3
|
||||
|
||||
#include "libircclient.h"
|
||||
|
||||
static irc_dcc_session_t * libirc_find_dcc_session (irc_session_t * session, irc_dcc_t dccid, int lock_list)
|
||||
{
|
||||
irc_dcc_session_t * s, *found = 0;
|
||||
|
||||
if ( lock_list )
|
||||
libirc_mutex_lock (&session->mutex_dcc);
|
||||
|
||||
for ( s = session->dcc_sessions; s; s = s->next )
|
||||
{
|
||||
if ( s->id == dccid )
|
||||
{
|
||||
found = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( found == 0 && lock_list )
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
static void libirc_dcc_destroy_nolock (irc_session_t * session, irc_dcc_t dccid)
|
||||
{
|
||||
irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 0);
|
||||
|
||||
if ( dcc )
|
||||
{
|
||||
if ( dcc->sock >= 0 )
|
||||
socket_close (&dcc->sock);
|
||||
|
||||
dcc->state = LIBIRC_STATE_REMOVED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void libirc_remove_dcc_session (irc_session_t * session, irc_dcc_session_t * dcc, int lock_list)
|
||||
{
|
||||
if ( dcc->sock >= 0 )
|
||||
socket_close (&dcc->sock);
|
||||
|
||||
if ( dcc->dccsend_file_fp )
|
||||
fclose (dcc->dccsend_file_fp);
|
||||
|
||||
dcc->dccsend_file_fp = 0;
|
||||
|
||||
libirc_mutex_destroy (&dcc->mutex_outbuf);
|
||||
|
||||
if ( lock_list )
|
||||
libirc_mutex_lock (&session->mutex_dcc);
|
||||
|
||||
if ( session->dcc_sessions != dcc )
|
||||
{
|
||||
irc_dcc_session_t * s;
|
||||
for ( s = session->dcc_sessions; s; s = s->next )
|
||||
{
|
||||
if ( s->next == dcc )
|
||||
{
|
||||
s->next = dcc->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
session->dcc_sessions = dcc->next;
|
||||
|
||||
if ( lock_list )
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
|
||||
free (dcc);
|
||||
}
|
||||
|
||||
|
||||
static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set, int * maxfd)
|
||||
{
|
||||
irc_dcc_session_t * dcc, *dcc_next;
|
||||
time_t now = time (0);
|
||||
|
||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||
|
||||
// Preprocessing DCC list:
|
||||
// - ask DCC send callbacks for data;
|
||||
// - remove unused DCC structures
|
||||
for ( dcc = ircsession->dcc_sessions; dcc; dcc = dcc_next )
|
||||
{
|
||||
dcc_next = dcc->next;
|
||||
|
||||
// Remove timed-out sessions
|
||||
if ( (dcc->state == LIBIRC_STATE_CONNECTING
|
||||
|| dcc->state == LIBIRC_STATE_INIT
|
||||
|| dcc->state == LIBIRC_STATE_LISTENING)
|
||||
&& now - dcc->timeout > ircsession->dcc_timeout )
|
||||
{
|
||||
// Inform the caller about DCC timeout.
|
||||
// Do not inform when state is LIBIRC_STATE_INIT - session
|
||||
// was initiated from someone else, and callbacks aren't set yet.
|
||||
if ( dcc->state != LIBIRC_STATE_INIT )
|
||||
{
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
|
||||
if ( dcc->cb )
|
||||
(*dcc->cb)(ircsession, dcc->id, LIBIRC_ERR_TIMEOUT, dcc->ctx, 0, 0);
|
||||
|
||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||
}
|
||||
|
||||
libirc_remove_dcc_session (ircsession, dcc, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're sending file, and the output buffer is empty, we need
|
||||
* to provide some data.
|
||||
*/
|
||||
if ( dcc->state == LIBIRC_STATE_CONNECTED
|
||||
&& dcc->dccmode == LIBIRC_DCC_SENDFILE
|
||||
&& dcc->dccsend_file_fp
|
||||
&& dcc->outgoing_offset == 0 )
|
||||
{
|
||||
int len = fread (dcc->outgoing_buf, 1, sizeof (dcc->outgoing_buf), dcc->dccsend_file_fp);
|
||||
|
||||
if ( len <= 0 )
|
||||
{
|
||||
int err = (len < 0 ? LIBIRC_ERR_READ : 0);
|
||||
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
|
||||
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0);
|
||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||
libirc_dcc_destroy_nolock (ircsession, dcc->id);
|
||||
}
|
||||
else
|
||||
dcc->outgoing_offset = len;
|
||||
}
|
||||
|
||||
// Clean up unused sessions
|
||||
if ( dcc->state == LIBIRC_STATE_REMOVED )
|
||||
libirc_remove_dcc_session (ircsession, dcc, 0);
|
||||
}
|
||||
|
||||
for ( dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next )
|
||||
{
|
||||
switch (dcc->state)
|
||||
{
|
||||
case LIBIRC_STATE_LISTENING:
|
||||
// While listening, only in_set descriptor should be set
|
||||
libirc_add_to_set (dcc->sock, in_set, maxfd);
|
||||
break;
|
||||
|
||||
case LIBIRC_STATE_CONNECTING:
|
||||
// While connection, only out_set descriptor should be set
|
||||
libirc_add_to_set (dcc->sock, out_set, maxfd);
|
||||
break;
|
||||
|
||||
case LIBIRC_STATE_CONNECTED:
|
||||
// Add input descriptor if there is space in input buffer
|
||||
// and it is DCC chat (during DCC send, there is nothing to recv)
|
||||
if ( dcc->incoming_offset < sizeof(dcc->incoming_buf) - 1 )
|
||||
libirc_add_to_set (dcc->sock, in_set, maxfd);
|
||||
|
||||
// Add output descriptor if there is something in output buffer
|
||||
libirc_mutex_lock (&dcc->mutex_outbuf);
|
||||
|
||||
if ( dcc->outgoing_offset > 0 )
|
||||
libirc_add_to_set (dcc->sock, out_set, maxfd);
|
||||
|
||||
libirc_mutex_unlock (&dcc->mutex_outbuf);
|
||||
break;
|
||||
|
||||
case LIBIRC_STATE_CONFIRM_SIZE:
|
||||
/*
|
||||
* If we're receiving file, then WE should confirm the transferred
|
||||
* part (so we have to sent data). But if we're sending the file,
|
||||
* then RECEIVER should confirm the packet, so we have to receive
|
||||
* data.
|
||||
*
|
||||
* We don't need to LOCK_DCC_OUTBUF - during file transfer, buffers
|
||||
* can't change asynchronously.
|
||||
*/
|
||||
if ( dcc->dccmode == LIBIRC_DCC_RECVFILE && dcc->outgoing_offset > 0 )
|
||||
libirc_add_to_set (dcc->sock, out_set, maxfd);
|
||||
|
||||
if ( dcc->dccmode == LIBIRC_DCC_SENDFILE && dcc->incoming_offset < 4 )
|
||||
libirc_add_to_set (dcc->sock, in_set, maxfd);
|
||||
}
|
||||
}
|
||||
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
}
|
||||
|
||||
|
||||
static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set)
|
||||
{
|
||||
irc_dcc_session_t * dcc;
|
||||
|
||||
/*
|
||||
* We need to use such a complex scheme here, because on every callback
|
||||
* a number of DCC sessions could be destroyed.
|
||||
*/
|
||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||
|
||||
for ( dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next )
|
||||
{
|
||||
if ( dcc->state == LIBIRC_STATE_LISTENING
|
||||
&& FD_ISSET (dcc->sock, in_set) )
|
||||
{
|
||||
socklen_t len = sizeof(dcc->remote_addr);
|
||||
int nsock, err = 0;
|
||||
|
||||
// New connection is available; accept it.
|
||||
if ( socket_accept (&dcc->sock, &nsock, (struct sockaddr *) &dcc->remote_addr, &len) )
|
||||
err = LIBIRC_ERR_ACCEPT;
|
||||
|
||||
// On success, change the active socket and change the state
|
||||
if ( err == 0 )
|
||||
{
|
||||
// close the listen socket, and replace it by a newly
|
||||
// accepted
|
||||
socket_close (&dcc->sock);
|
||||
dcc->sock = nsock;
|
||||
dcc->state = LIBIRC_STATE_CONNECTED;
|
||||
}
|
||||
|
||||
// If this is DCC chat, inform the caller about accept()
|
||||
// success or failure.
|
||||
// Otherwise (DCC send) there is no reason.
|
||||
if ( dcc->dccmode == LIBIRC_DCC_CHAT )
|
||||
{
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0);
|
||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||
}
|
||||
|
||||
if ( err )
|
||||
libirc_dcc_destroy_nolock (ircsession, dcc->id);
|
||||
}
|
||||
|
||||
if ( dcc->state == LIBIRC_STATE_CONNECTING
|
||||
&& FD_ISSET (dcc->sock, out_set) )
|
||||
{
|
||||
// Now we have to determine whether the socket is connected
|
||||
// or the connect is failed
|
||||
struct sockaddr_in saddr;
|
||||
socklen_t slen = sizeof(saddr);
|
||||
int err = 0;
|
||||
|
||||
if ( getpeername (dcc->sock, (struct sockaddr*)&saddr, &slen) < 0 )
|
||||
err = LIBIRC_ERR_CONNECT;
|
||||
|
||||
// On success, change the state
|
||||
if ( err == 0 )
|
||||
dcc->state = LIBIRC_STATE_CONNECTED;
|
||||
|
||||
// If this is DCC chat, inform the caller about connect()
|
||||
// success or failure.
|
||||
// Otherwise (DCC send) there is no reason.
|
||||
if ( dcc->dccmode == LIBIRC_DCC_CHAT )
|
||||
{
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0);
|
||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||
}
|
||||
|
||||
if ( err )
|
||||
libirc_dcc_destroy_nolock (ircsession, dcc->id);
|
||||
}
|
||||
|
||||
if ( dcc->state == LIBIRC_STATE_CONNECTED
|
||||
|| dcc->state == LIBIRC_STATE_CONFIRM_SIZE )
|
||||
{
|
||||
if ( FD_ISSET (dcc->sock, in_set) )
|
||||
{
|
||||
int length, offset = 0, err = 0;
|
||||
|
||||
unsigned int amount = sizeof (dcc->incoming_buf) - dcc->incoming_offset;
|
||||
|
||||
length = socket_recv (&dcc->sock, dcc->incoming_buf + dcc->incoming_offset, amount);
|
||||
|
||||
if ( length < 0 )
|
||||
{
|
||||
err = LIBIRC_ERR_READ;
|
||||
}
|
||||
else if ( length == 0 )
|
||||
{
|
||||
err = LIBIRC_ERR_CLOSED;
|
||||
|
||||
if ( dcc->dccsend_file_fp )
|
||||
{
|
||||
fclose (dcc->dccsend_file_fp);
|
||||
dcc->dccsend_file_fp = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dcc->incoming_offset += length;
|
||||
|
||||
if ( dcc->dccmode != LIBIRC_DCC_CHAT )
|
||||
offset = dcc->incoming_offset;
|
||||
else
|
||||
offset = libirc_findcrorlf (dcc->incoming_buf, dcc->incoming_offset);
|
||||
|
||||
/*
|
||||
* In LIBIRC_STATE_CONFIRM_SIZE state we don't call any
|
||||
* callbacks (except there is an error). We just receive
|
||||
* the data, and compare it with the amount sent.
|
||||
*/
|
||||
if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE )
|
||||
{
|
||||
if ( dcc->dccmode != LIBIRC_DCC_SENDFILE )
|
||||
abort();
|
||||
|
||||
if ( dcc->incoming_offset == 4 )
|
||||
{
|
||||
unsigned int received_size = ntohl (*((unsigned int*)dcc->incoming_buf));
|
||||
|
||||
// Sent size confirmed
|
||||
if ( dcc->file_confirm_offset == received_size )
|
||||
{
|
||||
dcc->state = LIBIRC_STATE_CONNECTED;
|
||||
dcc->incoming_offset = 0;
|
||||
}
|
||||
else
|
||||
err = LIBIRC_ERR_WRITE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If it is DCC_CHAT, we send a 0-terminated string
|
||||
* (which is smaller than offset). Otherwise we send
|
||||
* a full buffer.
|
||||
*/
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
|
||||
if ( dcc->dccmode != LIBIRC_DCC_CHAT )
|
||||
{
|
||||
if ( dcc->dccmode != LIBIRC_DCC_RECVFILE )
|
||||
abort();
|
||||
|
||||
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, dcc->incoming_buf, offset);
|
||||
|
||||
/*
|
||||
* If the session is not terminated in callback,
|
||||
* put the sent amount into the sent_packet_size_net_byteorder
|
||||
*/
|
||||
if ( dcc->state != LIBIRC_STATE_REMOVED )
|
||||
{
|
||||
dcc->state = LIBIRC_STATE_CONFIRM_SIZE;
|
||||
dcc->file_confirm_offset += offset;
|
||||
*((unsigned int*)dcc->outgoing_buf) = htonl (dcc->file_confirm_offset);
|
||||
dcc->outgoing_offset = 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, dcc->incoming_buf, strlen(dcc->incoming_buf));
|
||||
|
||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||
|
||||
if ( dcc->incoming_offset - offset > 0 )
|
||||
memmove (dcc->incoming_buf, dcc->incoming_buf + offset, dcc->incoming_offset - offset);
|
||||
|
||||
dcc->incoming_offset -= offset;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If error arises somewhere above, we inform the caller
|
||||
* of failure, and destroy this session.
|
||||
*/
|
||||
if ( err )
|
||||
{
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0);
|
||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||
libirc_dcc_destroy_nolock (ircsession, dcc->id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Session might be closed (with sock = -1) after the in_set
|
||||
* processing, so before out_set processing we should check
|
||||
* for this case
|
||||
*/
|
||||
if ( dcc->state == LIBIRC_STATE_REMOVED )
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Write bit set - we can send() something, and it won't block.
|
||||
*/
|
||||
if ( FD_ISSET (dcc->sock, out_set) )
|
||||
{
|
||||
int length, offset, err = 0;
|
||||
|
||||
/*
|
||||
* Because in some cases outgoing_buf could be changed
|
||||
* asynchronously (by another thread), we should lock
|
||||
* it.
|
||||
*/
|
||||
libirc_mutex_lock (&dcc->mutex_outbuf);
|
||||
|
||||
offset = dcc->outgoing_offset;
|
||||
|
||||
if ( offset > 0 )
|
||||
{
|
||||
length = socket_send (&dcc->sock, dcc->outgoing_buf, offset);
|
||||
|
||||
if ( length < 0 )
|
||||
err = LIBIRC_ERR_WRITE;
|
||||
else if ( length == 0 )
|
||||
err = LIBIRC_ERR_CLOSED;
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If this was DCC_SENDFILE, and we just sent a packet,
|
||||
* change the state to wait for confirmation (and store
|
||||
* sent packet size)
|
||||
*/
|
||||
if ( dcc->state == LIBIRC_STATE_CONNECTED
|
||||
&& dcc->dccmode == LIBIRC_DCC_SENDFILE )
|
||||
{
|
||||
dcc->file_confirm_offset += offset;
|
||||
dcc->state = LIBIRC_STATE_CONFIRM_SIZE;
|
||||
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
libirc_mutex_unlock (&dcc->mutex_outbuf);
|
||||
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, offset);
|
||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||
libirc_mutex_lock (&dcc->mutex_outbuf);
|
||||
}
|
||||
|
||||
if ( dcc->outgoing_offset - length > 0 )
|
||||
memmove (dcc->outgoing_buf, dcc->outgoing_buf + length, dcc->outgoing_offset - length);
|
||||
|
||||
dcc->outgoing_offset -= length;
|
||||
|
||||
/*
|
||||
* If we just sent the confirmation data, change state
|
||||
* back.
|
||||
*/
|
||||
if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE
|
||||
&& dcc->dccmode == LIBIRC_DCC_RECVFILE
|
||||
&& dcc->outgoing_offset == 0 )
|
||||
{
|
||||
/*
|
||||
* If the file is already received, we should inform
|
||||
* the caller, and close the session.
|
||||
*/
|
||||
if ( dcc->received_file_size == dcc->file_confirm_offset )
|
||||
{
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
libirc_mutex_unlock (&dcc->mutex_outbuf);
|
||||
(*dcc->cb)(ircsession, dcc->id, 0, dcc->ctx, 0, 0);
|
||||
libirc_dcc_destroy_nolock (ircsession, dcc->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Continue to receive the file */
|
||||
dcc->state = LIBIRC_STATE_CONNECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libirc_mutex_unlock (&dcc->mutex_outbuf);
|
||||
|
||||
/*
|
||||
* If error arises somewhere above, we inform the caller
|
||||
* of failure, and destroy this session.
|
||||
*/
|
||||
if ( err )
|
||||
{
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0);
|
||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||
|
||||
libirc_dcc_destroy_nolock (ircsession, dcc->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||
}
|
||||
|
||||
|
||||
static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, unsigned short port, int dccmode, void * ctx, irc_dcc_session_t ** pdcc)
|
||||
{
|
||||
irc_dcc_session_t * dcc = malloc (sizeof(irc_dcc_session_t));
|
||||
|
||||
if ( !dcc )
|
||||
return LIBIRC_ERR_NOMEM;
|
||||
|
||||
// setup
|
||||
memset (dcc, 0, sizeof(irc_dcc_session_t));
|
||||
|
||||
dcc->dccsend_file_fp = 0;
|
||||
|
||||
if ( libirc_mutex_init (&dcc->mutex_outbuf) )
|
||||
goto cleanup_exit_error;
|
||||
|
||||
if ( socket_create (PF_INET, SOCK_STREAM, &dcc->sock) )
|
||||
goto cleanup_exit_error;
|
||||
|
||||
if ( !ip )
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
unsigned long arg = 1;
|
||||
|
||||
setsockopt (dcc->sock, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, sizeof(arg));
|
||||
|
||||
memset (&saddr, 0, sizeof(saddr));
|
||||
saddr.sin_family = AF_INET;
|
||||
memcpy (&saddr.sin_addr, &session->local_addr, sizeof(session->local_addr));
|
||||
saddr.sin_port = htons (0);
|
||||
|
||||
if ( bind (dcc->sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0 )
|
||||
goto cleanup_exit_error;
|
||||
|
||||
if ( listen (dcc->sock, 5) < 0 )
|
||||
goto cleanup_exit_error;
|
||||
|
||||
dcc->state = LIBIRC_STATE_LISTENING;
|
||||
}
|
||||
else
|
||||
{
|
||||
// make socket non-blocking, so connect() call won't block
|
||||
if ( socket_make_nonblocking (&dcc->sock) )
|
||||
goto cleanup_exit_error;
|
||||
|
||||
memset (&dcc->remote_addr, 0, sizeof(dcc->remote_addr));
|
||||
dcc->remote_addr.sin_family = AF_INET;
|
||||
dcc->remote_addr.sin_addr.s_addr = htonl (ip); // what idiot came up with idea to send IP address in host-byteorder?
|
||||
dcc->remote_addr.sin_port = htons(port);
|
||||
|
||||
dcc->state = LIBIRC_STATE_INIT;
|
||||
}
|
||||
|
||||
dcc->dccmode = dccmode;
|
||||
dcc->ctx = ctx;
|
||||
time (&dcc->timeout);
|
||||
|
||||
// and store it
|
||||
libirc_mutex_lock (&session->mutex_dcc);
|
||||
|
||||
dcc->id = session->dcc_last_id++;
|
||||
dcc->next = session->dcc_sessions;
|
||||
session->dcc_sessions = dcc;
|
||||
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
|
||||
*pdcc = dcc;
|
||||
return 0;
|
||||
|
||||
cleanup_exit_error:
|
||||
if ( dcc->sock >= 0 )
|
||||
socket_close (&dcc->sock);
|
||||
|
||||
free (dcc);
|
||||
return LIBIRC_ERR_SOCKET;
|
||||
}
|
||||
|
||||
|
||||
int irc_dcc_destroy (irc_session_t * session, irc_dcc_t dccid)
|
||||
{
|
||||
// This function doesn't actually destroy the session; it just changes
|
||||
// its state to "removed" and closes the socket. The memory is actually
|
||||
// freed after the processing loop.
|
||||
irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 1);
|
||||
|
||||
if ( !dcc )
|
||||
return 1;
|
||||
|
||||
if ( dcc->sock >= 0 )
|
||||
socket_close (&dcc->sock);
|
||||
|
||||
dcc->state = LIBIRC_STATE_REMOVED;
|
||||
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int irc_dcc_chat (irc_session_t * session, void * ctx, const char * nick, irc_dcc_callback_t callback, irc_dcc_t * dccid)
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
socklen_t len = sizeof(saddr);
|
||||
char cmdbuf[128], notbuf[128];
|
||||
irc_dcc_session_t * dcc;
|
||||
int err;
|
||||
|
||||
if ( session->state != LIBIRC_STATE_CONNECTED )
|
||||
{
|
||||
session->lasterror = LIBIRC_ERR_STATE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = libirc_new_dcc_session (session, 0, 0, LIBIRC_DCC_CHAT, ctx, &dcc);
|
||||
|
||||
if ( err )
|
||||
{
|
||||
session->lasterror = err;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( getsockname (dcc->sock, (struct sockaddr*) &saddr, &len) < 0 )
|
||||
{
|
||||
session->lasterror = LIBIRC_ERR_SOCKET;
|
||||
libirc_remove_dcc_session (session, dcc, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sprintf (notbuf, "DCC Chat (%s)", inet_ntoa (saddr.sin_addr));
|
||||
sprintf (cmdbuf, "DCC CHAT chat %lu %u", (unsigned long) ntohl (saddr.sin_addr.s_addr), ntohs (saddr.sin_port));
|
||||
|
||||
if ( irc_cmd_notice (session, nick, notbuf)
|
||||
|| irc_cmd_ctcp_request (session, nick, cmdbuf) )
|
||||
{
|
||||
libirc_remove_dcc_session (session, dcc, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
*dccid = dcc->id;
|
||||
dcc->cb = callback;
|
||||
dcc->dccmode = LIBIRC_DCC_CHAT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int irc_dcc_msg (irc_session_t * session, irc_dcc_t dccid, const char * text)
|
||||
{
|
||||
irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 1);
|
||||
|
||||
if ( !dcc )
|
||||
return 1;
|
||||
|
||||
if ( dcc->dccmode != LIBIRC_DCC_CHAT )
|
||||
{
|
||||
session->lasterror = LIBIRC_ERR_INVAL;
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( (strlen(text) + 2) >= (sizeof(dcc->outgoing_buf) - dcc->outgoing_offset) )
|
||||
{
|
||||
session->lasterror = LIBIRC_ERR_NOMEM;
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
libirc_mutex_lock (&dcc->mutex_outbuf);
|
||||
|
||||
strcpy (dcc->outgoing_buf + dcc->outgoing_offset, text);
|
||||
dcc->outgoing_offset += strlen (text);
|
||||
dcc->outgoing_buf[dcc->outgoing_offset++] = 0x0D;
|
||||
dcc->outgoing_buf[dcc->outgoing_offset++] = 0x0A;
|
||||
|
||||
libirc_mutex_unlock (&dcc->mutex_outbuf);
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void libirc_dcc_request (irc_session_t * session, const char * nick, const char * req)
|
||||
{
|
||||
char filenamebuf[256];
|
||||
unsigned long ip, size;
|
||||
unsigned short port;
|
||||
|
||||
if ( sscanf (req, "DCC CHAT chat %lu %hu", &ip, &port) == 2 )
|
||||
{
|
||||
if ( session->callbacks.event_dcc_chat_req )
|
||||
{
|
||||
irc_dcc_session_t * dcc;
|
||||
|
||||
int err = libirc_new_dcc_session (session, ip, port, LIBIRC_DCC_CHAT, 0, &dcc);
|
||||
if ( err )
|
||||
{
|
||||
session->lasterror = err;
|
||||
return;
|
||||
}
|
||||
|
||||
(*session->callbacks.event_dcc_chat_req) (session,
|
||||
nick,
|
||||
inet_ntoa (dcc->remote_addr.sin_addr),
|
||||
dcc->id);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if ( sscanf (req, "DCC SEND %s %lu %hu %lu", filenamebuf, &ip, &port, &size) == 4 )
|
||||
{
|
||||
if ( session->callbacks.event_dcc_send_req )
|
||||
{
|
||||
irc_dcc_session_t * dcc;
|
||||
|
||||
int err = libirc_new_dcc_session (session, ip, port, LIBIRC_DCC_RECVFILE, 0, &dcc);
|
||||
if ( err )
|
||||
{
|
||||
session->lasterror = err;
|
||||
return;
|
||||
}
|
||||
|
||||
(*session->callbacks.event_dcc_send_req) (session,
|
||||
nick,
|
||||
inet_ntoa (dcc->remote_addr.sin_addr),
|
||||
filenamebuf,
|
||||
size,
|
||||
dcc->id);
|
||||
|
||||
dcc->received_file_size = size;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#if defined (ENABLE_DEBUG)
|
||||
fprintf (stderr, "BUG: Unhandled DCC message: %s\n", req);
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int irc_dcc_accept (irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dcc_callback_t callback)
|
||||
{
|
||||
irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 1);
|
||||
|
||||
if ( !dcc )
|
||||
return 1;
|
||||
|
||||
if ( dcc->state != LIBIRC_STATE_INIT )
|
||||
{
|
||||
session->lasterror = LIBIRC_ERR_STATE;
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dcc->cb = callback;
|
||||
dcc->ctx = ctx;
|
||||
|
||||
// Initiate the connect
|
||||
if ( socket_connect (&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof(dcc->remote_addr)) )
|
||||
{
|
||||
libirc_dcc_destroy_nolock (session, dccid);
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
session->lasterror = LIBIRC_ERR_CONNECT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
dcc->state = LIBIRC_STATE_CONNECTING;
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int irc_dcc_decline (irc_session_t * session, irc_dcc_t dccid)
|
||||
{
|
||||
irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 1);
|
||||
|
||||
if ( !dcc )
|
||||
return 1;
|
||||
|
||||
if ( dcc->state != LIBIRC_STATE_INIT )
|
||||
{
|
||||
session->lasterror = LIBIRC_ERR_STATE;
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
libirc_dcc_destroy_nolock (session, dccid);
|
||||
libirc_mutex_unlock (&session->mutex_dcc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int irc_dcc_sendfile (irc_session_t * session, void * ctx, const char * nick, const char * filename, irc_dcc_callback_t callback, irc_dcc_t * dccid)
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
socklen_t len = sizeof(saddr);
|
||||
char cmdbuf[128], notbuf[128];
|
||||
irc_dcc_session_t * dcc;
|
||||
const char * p;
|
||||
int err;
|
||||
long filesize;
|
||||
|
||||
if ( !session || !dccid || !filename || !callback )
|
||||
{
|
||||
session->lasterror = LIBIRC_ERR_INVAL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( session->state != LIBIRC_STATE_CONNECTED )
|
||||
{
|
||||
session->lasterror = LIBIRC_ERR_STATE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( (err = libirc_new_dcc_session (session, 0, 0, LIBIRC_DCC_SENDFILE, ctx, &dcc)) != 0 )
|
||||
{
|
||||
session->lasterror = err;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( (dcc->dccsend_file_fp = fopen (filename, "rb")) == 0 )
|
||||
{
|
||||
libirc_remove_dcc_session (session, dcc, 1);
|
||||
session->lasterror = LIBIRC_ERR_OPENFILE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get file length */
|
||||
if ( fseek (dcc->dccsend_file_fp, 0, SEEK_END)
|
||||
|| (filesize = ftell (dcc->dccsend_file_fp)) == -1
|
||||
|| fseek (dcc->dccsend_file_fp, 0, SEEK_SET) )
|
||||
{
|
||||
libirc_remove_dcc_session (session, dcc, 1);
|
||||
session->lasterror = LIBIRC_ERR_NODCCSEND;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( getsockname (dcc->sock, (struct sockaddr*) &saddr, &len) < 0 )
|
||||
{
|
||||
libirc_remove_dcc_session (session, dcc, 1);
|
||||
session->lasterror = LIBIRC_ERR_SOCKET;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Remove path from the filename
|
||||
if ( (p = strrchr (filename, '\\')) == 0
|
||||
&& (p = strrchr (filename, '/')) == 0 )
|
||||
p = filename;
|
||||
else
|
||||
p++; // skip directory slash
|
||||
|
||||
sprintf (notbuf, "DCC Send %s (%s)", p, inet_ntoa (saddr.sin_addr));
|
||||
sprintf (cmdbuf, "DCC SEND %s %lu %u %ld", p, (unsigned long) ntohl (saddr.sin_addr.s_addr), ntohs (saddr.sin_port), filesize);
|
||||
|
||||
if ( irc_cmd_notice (session, nick, notbuf)
|
||||
|| irc_cmd_ctcp_request (session, nick, cmdbuf) )
|
||||
{
|
||||
libirc_remove_dcc_session (session, dcc, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
*dccid = dcc->id;
|
||||
dcc->cb = callback;
|
||||
|
||||
return 0;
|
||||
}
|
52
source/shared_lib/sources/libircclient/src/errors.c
Normal file
52
source/shared_lib/sources/libircclient/src/errors.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2009 Georgy Yunaev gyunaev@ulduzsoft.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public
|
||||
* License for more details.
|
||||
*/
|
||||
#include "libircclient.h"
|
||||
#include "libirc_session.h"
|
||||
|
||||
static const char * libirc_strerror[LIBIRC_ERR_MAX] =
|
||||
{
|
||||
"No error",
|
||||
"Invalid argument",
|
||||
"Host not resolved",
|
||||
"Socket error",
|
||||
"Could not connect",
|
||||
"Remote connection closed",
|
||||
"Out of memory",
|
||||
"Could not accept new connection",
|
||||
"Object not found",
|
||||
"Could not DCC send this object",
|
||||
"Read error",
|
||||
"Write error",
|
||||
"Illegal operation for this state",
|
||||
"Timeout error",
|
||||
"Could not open file",
|
||||
"IRC session terminated",
|
||||
"IPv6 not supported",
|
||||
};
|
||||
|
||||
|
||||
int irc_errno (irc_session_t * session)
|
||||
{
|
||||
return session->lasterror;
|
||||
}
|
||||
|
||||
|
||||
const char * irc_strerror (int ircerrno)
|
||||
{
|
||||
if ( ircerrno >= 0 && ircerrno < LIBIRC_ERR_MAX )
|
||||
return libirc_strerror[ircerrno];
|
||||
else
|
||||
return "Invalid irc_errno value";
|
||||
}
|
||||
|
1147
source/shared_lib/sources/libircclient/src/libircclient.c
Normal file
1147
source/shared_lib/sources/libircclient/src/libircclient.c
Normal file
File diff suppressed because it is too large
Load Diff
47
source/shared_lib/sources/libircclient/src/libircclient.def
Normal file
47
source/shared_lib/sources/libircclient/src/libircclient.def
Normal file
@@ -0,0 +1,47 @@
|
||||
LIBRARY libircclient
|
||||
EXPORTS
|
||||
irc_create_session
|
||||
irc_destroy_session
|
||||
irc_connect
|
||||
irc_connect6
|
||||
irc_disconnect
|
||||
irc_run
|
||||
irc_add_select_descriptors
|
||||
irc_process_select_descriptors
|
||||
irc_send_raw
|
||||
irc_cmd_quit
|
||||
irc_cmd_join
|
||||
irc_cmd_msg
|
||||
irc_cmd_me
|
||||
irc_cmd_notice
|
||||
irc_cmd_kick
|
||||
irc_cmd_ctcp_request
|
||||
irc_cmd_ctcp_reply
|
||||
irc_target_get_nick
|
||||
irc_target_get_host
|
||||
irc_dcc_chat
|
||||
irc_dcc_msg
|
||||
irc_dcc_accept
|
||||
irc_dcc_decline
|
||||
irc_dcc_sendfile
|
||||
irc_dcc_destroy
|
||||
irc_get_version
|
||||
irc_set_ctx
|
||||
irc_get_ctx
|
||||
irc_errno
|
||||
irc_strerror
|
||||
irc_option_set
|
||||
irc_option_reset
|
||||
irc_is_connected
|
||||
irc_cmd_part
|
||||
irc_cmd_invite
|
||||
irc_cmd_names
|
||||
irc_cmd_list
|
||||
irc_cmd_topic
|
||||
irc_cmd_channel_mode
|
||||
irc_cmd_user_mode
|
||||
irc_cmd_nick
|
||||
irc_cmd_whois
|
||||
irc_color_strip_from_mirc
|
||||
irc_color_convert_from_mirc
|
||||
irc_color_convert_to_mirc
|
BIN
source/shared_lib/sources/libircclient/src/libircclient.obj
Normal file
BIN
source/shared_lib/sources/libircclient/src/libircclient.obj
Normal file
Binary file not shown.
152
source/shared_lib/sources/libircclient/src/portable.c
Normal file
152
source/shared_lib/sources/libircclient/src/portable.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2009 Georgy Yunaev gyunaev@ulduzsoft.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public
|
||||
* License for more details.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined (WIN32)
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined (ENABLE_THREADS)
|
||||
#include <pthread.h>
|
||||
typedef pthread_mutex_t port_mutex_t;
|
||||
|
||||
#if !defined (PTHREAD_MUTEX_RECURSIVE) && defined (PTHREAD_MUTEX_RECURSIVE_NP)
|
||||
#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined (ENABLE_THREADS)
|
||||
typedef CRITICAL_SECTION port_mutex_t;
|
||||
#endif
|
||||
|
||||
#define inline
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#define strncasecmp _strnicmp
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (ENABLE_THREADS)
|
||||
|
||||
|
||||
static inline int libirc_mutex_init (port_mutex_t * mutex)
|
||||
{
|
||||
#if defined (WIN32)
|
||||
InitializeCriticalSection (mutex);
|
||||
return 0;
|
||||
#elif defined (PTHREAD_MUTEX_RECURSIVE)
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
return (pthread_mutexattr_init (&attr)
|
||||
|| pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE)
|
||||
|| pthread_mutex_init (mutex, &attr));
|
||||
#else /* !defined (PTHREAD_MUTEX_RECURSIVE) */
|
||||
|
||||
return pthread_mutex_init (mutex, 0);
|
||||
|
||||
#endif /* defined (WIN32) */
|
||||
}
|
||||
|
||||
|
||||
static inline void libirc_mutex_destroy (port_mutex_t * mutex)
|
||||
{
|
||||
#if defined (WIN32)
|
||||
DeleteCriticalSection (mutex);
|
||||
#else
|
||||
pthread_mutex_destroy (mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline void libirc_mutex_lock (port_mutex_t * mutex)
|
||||
{
|
||||
#if defined (WIN32)
|
||||
EnterCriticalSection (mutex);
|
||||
#else
|
||||
pthread_mutex_lock (mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline void libirc_mutex_unlock (port_mutex_t * mutex)
|
||||
{
|
||||
#if defined (WIN32)
|
||||
LeaveCriticalSection (mutex);
|
||||
#else
|
||||
pthread_mutex_unlock (mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef void * port_mutex_t;
|
||||
|
||||
static inline int libirc_mutex_init (port_mutex_t * mutex) { return 0; }
|
||||
static inline void libirc_mutex_destroy (port_mutex_t * mutex) {}
|
||||
static inline void libirc_mutex_lock (port_mutex_t * mutex) {}
|
||||
static inline void libirc_mutex_unlock (port_mutex_t * mutex) {}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Stub for WIN32 dll to initialize winsock API
|
||||
*/
|
||||
#if defined (_USRDLL)
|
||||
BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
WORD wVersionRequested = MAKEWORD (1, 1);
|
||||
WSADATA wsaData;
|
||||
|
||||
switch(fdwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
if ( WSAStartup (wVersionRequested, &wsaData) != 0 )
|
||||
return FALSE;
|
||||
|
||||
DisableThreadLibraryCalls (hinstDll);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
WSACleanup();
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
142
source/shared_lib/sources/libircclient/src/sockets.c
Normal file
142
source/shared_lib/sources/libircclient/src/sockets.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2009 Georgy Yunaev gyunaev@ulduzsoft.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public
|
||||
* License for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The sockets interface was moved out to simplify going OpenSSL integration.
|
||||
*/
|
||||
#if !defined (WIN32)
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define IS_SOCKET_ERROR(a) ((a)<0)
|
||||
typedef int socket_t;
|
||||
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define IS_SOCKET_ERROR(a) ((a)==SOCKET_ERROR)
|
||||
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define EINPROGRESS WSAEINPROGRESS
|
||||
#define EINTR WSAEINTR
|
||||
|
||||
typedef SOCKET socket_t;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
|
||||
static int socket_error()
|
||||
{
|
||||
#if !defined (WIN32)
|
||||
return errno;
|
||||
#else
|
||||
return WSAGetLastError();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int socket_create (int domain, int type, socket_t * sock)
|
||||
{
|
||||
*sock = socket (domain, type, 0);
|
||||
return IS_SOCKET_ERROR(*sock) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
static int socket_make_nonblocking (socket_t * sock)
|
||||
{
|
||||
#if !defined (WIN32)
|
||||
return fcntl (*sock, F_SETFL, fcntl (*sock, F_GETFL,0 ) | O_NONBLOCK) != 0;
|
||||
#else
|
||||
unsigned long mode = 0;
|
||||
return ioctlsocket (*sock, FIONBIO, &mode) == SOCKET_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int socket_close (socket_t * sock)
|
||||
{
|
||||
#if !defined (WIN32)
|
||||
close (*sock);
|
||||
#else
|
||||
closesocket (*sock);
|
||||
#endif
|
||||
|
||||
*sock = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int socket_connect (socket_t * sock, const struct sockaddr *saddr, socklen_t len)
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
if ( connect (*sock, saddr, len) < 0 )
|
||||
{
|
||||
if ( socket_error() == EINTR )
|
||||
continue;
|
||||
|
||||
if ( socket_error() != EINPROGRESS && socket_error() != EWOULDBLOCK )
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int socket_accept (socket_t * sock, socket_t * newsock, struct sockaddr *saddr, socklen_t * len)
|
||||
{
|
||||
while ( IS_SOCKET_ERROR(*newsock = accept (*sock, saddr, len)) )
|
||||
{
|
||||
if ( socket_error() == EINTR )
|
||||
continue;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int socket_recv (socket_t * sock, void * buf, size_t len)
|
||||
{
|
||||
int length;
|
||||
|
||||
while ( (length = recv (*sock, buf, len, 0)) < 0
|
||||
&& socket_error() == EINTR )
|
||||
continue;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
static int socket_send (socket_t * sock, const void *buf, size_t len)
|
||||
{
|
||||
int length;
|
||||
|
||||
while ( (length = send (*sock, buf, len, 0)) < 0
|
||||
&& socket_error() == EINTR )
|
||||
continue;
|
||||
|
||||
return length;
|
||||
}
|
106
source/shared_lib/sources/libircclient/src/utils.c
Normal file
106
source/shared_lib/sources/libircclient/src/utils.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2009 Georgy Yunaev gyunaev@ulduzsoft.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public
|
||||
* License for more details.
|
||||
*/
|
||||
|
||||
static void libirc_add_to_set (int fd, fd_set *set, int * maxfd)
|
||||
{
|
||||
FD_SET (fd, set);
|
||||
|
||||
if ( *maxfd < fd )
|
||||
*maxfd = fd;
|
||||
}
|
||||
|
||||
#if defined (ENABLE_DEBUG)
|
||||
static void libirc_dump_data (const char * prefix, const char * buf, unsigned int length)
|
||||
{
|
||||
printf ("%s: ", prefix);
|
||||
for ( ; length > 0; length -- )
|
||||
printf ("%c", *buf++);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Finds a separator (\x0D\x0A), which separates two lines.
|
||||
*/
|
||||
static int libirc_findcrlf (const char * buf, int length)
|
||||
{
|
||||
int offset = 0;
|
||||
for ( ; offset < (length - 1); offset++ )
|
||||
if ( buf[offset] == 0x0D && buf[offset+1] == 0x0A )
|
||||
return (offset + 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int libirc_findcrorlf (char * buf, int length)
|
||||
{
|
||||
int offset = 0;
|
||||
for ( ; offset < length; offset++ )
|
||||
{
|
||||
if ( buf[offset] == 0x0D || buf[offset] == 0x0A )
|
||||
{
|
||||
buf[offset++] = '\0';
|
||||
|
||||
if ( offset < (length - 1)
|
||||
&& (buf[offset] == 0x0D || buf[offset] == 0x0A) )
|
||||
offset++;
|
||||
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void libirc_event_ctcp_internal (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count)
|
||||
{
|
||||
if ( origin )
|
||||
{
|
||||
char nickbuf[128], textbuf[256];
|
||||
irc_target_get_nick (origin, nickbuf, sizeof(nickbuf));
|
||||
|
||||
if ( strstr (params[0], "PING") == params[0] )
|
||||
irc_cmd_ctcp_reply (session, nickbuf, params[0]);
|
||||
else if ( !strcmp (params[0], "VERSION") )
|
||||
{
|
||||
unsigned int high, low;
|
||||
irc_get_version (&high, &low);
|
||||
|
||||
sprintf (textbuf, "VERSION libirc by Georgy Yunaev ver.%d.%d", high, low);
|
||||
irc_cmd_ctcp_reply (session, nickbuf, textbuf);
|
||||
}
|
||||
else if ( !strcmp (params[0], "FINGER") )
|
||||
{
|
||||
sprintf (textbuf, "FINGER %s (%s) Idle 0 seconds",
|
||||
session->username ? session->username : "nobody",
|
||||
session->realname ? session->realname : "noname");
|
||||
|
||||
irc_cmd_ctcp_reply (session, nickbuf, textbuf);
|
||||
}
|
||||
else if ( !strcmp (params[0], "TIME") )
|
||||
{
|
||||
time_t now = time(0);
|
||||
|
||||
#if defined (ENABLE_THREADS) && defined (HAVE_LOCALTIME_R)
|
||||
struct tm tmtmp, *ltime = localtime_r (&now, &tmtmp);
|
||||
#else
|
||||
struct tm * ltime = localtime (&now);
|
||||
#endif
|
||||
strftime (textbuf, sizeof(textbuf), "%a %b %e %H:%M:%S %Z %Y", ltime);
|
||||
irc_cmd_ctcp_reply (session, nickbuf, textbuf);
|
||||
}
|
||||
}
|
||||
}
|
103
source/shared_lib/sources/libircclient/src/win32/libdynamic.dsp
Normal file
103
source/shared_lib/sources/libircclient/src/win32/libdynamic.dsp
Normal file
@@ -0,0 +1,103 @@
|
||||
# Microsoft Developer Studio Project File - Name="libdynamic" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=libdynamic - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "libdynamic.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "libdynamic.mak" CFG="libdynamic - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "libdynamic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "libdynamic - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "libdynamic - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "libdynamic-release"
|
||||
# PROP Intermediate_Dir "libdynamic-release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBDYNAMIC_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "ENABLE_THREADS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 wsock32.lib /nologo /dll /pdb:none /machine:I386 /out:"libdynamic-release/libircclient.dll"
|
||||
|
||||
!ELSEIF "$(CFG)" == "libdynamic - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "libdynamic-debug"
|
||||
# PROP Intermediate_Dir "libdynamic-debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBDYNAMIC_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "ENABLE_THREADS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 wsock32.lib /nologo /dll /debug /machine:I386 /out:"libdynamic-debug/libircclient.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "libdynamic - Win32 Release"
|
||||
# Name "libdynamic - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\libircclient.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\libircclient.def
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
@@ -0,0 +1,56 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "libdynamic"=".\libdynamic.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "libstatic"=".\libstatic.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "spammer"=".\spammer.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name libdynamic
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
@@ -0,0 +1,92 @@
|
||||
# Microsoft Developer Studio Project File - Name="libstatic" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=libstatic - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "libstatic.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "libstatic.mak" CFG="libstatic - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "libstatic - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "libstatic - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "libstatic - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "libstatic-release"
|
||||
# PROP Intermediate_Dir "libstatic-release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "ENABLE_THREADS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo /out:"libstatic-release\libircclient-static.lib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "libstatic - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "libstatic-debug"
|
||||
# PROP Intermediate_Dir "libstatic-debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "ENABLE_THREADS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "libstatic - Win32 Release"
|
||||
# Name "libstatic - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\libircclient.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
mkdir -p win32/lib
|
||||
mkdir -p win32/include
|
||||
mkdir -p win32/examples
|
||||
cp libdynamic-release/*.lib win32/lib/
|
||||
cp libdynamic-release/*.dll win32/lib/
|
||||
cp libstatic-release/*.lib win32/lib/
|
||||
cp ../../include/libircclient.h win32/include/
|
||||
cp ../../include/libirc_errors.h win32/include/
|
||||
cp ../../include/libirc_events.h win32/include/
|
||||
cp -r ../../examples/* win32/examples/
|
||||
cp spammer.dsp win32/examples/
|
||||
cd win32
|
||||
zip -r ../libircclient-win32-vc-1.2.zip .
|
||||
cd ..
|
||||
rm -rf win32
|
||||
|
||||
mkdir doc
|
||||
cp ../../doc/html/* doc/
|
||||
cd doc
|
||||
zip -r ../libircclient-dochtml-1.2.zip .
|
||||
cd ..
|
||||
rm -rf doc
|
96
source/shared_lib/sources/libircclient/src/win32/spammer.dsp
Normal file
96
source/shared_lib/sources/libircclient/src/win32/spammer.dsp
Normal file
@@ -0,0 +1,96 @@
|
||||
# Microsoft Developer Studio Project File - Name="spammer" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=spammer - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "spammer.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "spammer.mak" CFG="spammer - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "spammer - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "spammer - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "spammer - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 libdynamic-release/libircclient.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "spammer - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 libdynamic-release/libircclient.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "spammer - Win32 Release"
|
||||
# Name "spammer - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\examples\spammer.c
|
||||
# ADD CPP /I "../../include"
|
||||
# SUBTRACT CPP /I "../include"
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
Reference in New Issue
Block a user