├── .cvsignore ├── conf ├── .cvsignore └── Makefile.am ├── contrib ├── .cvsignore ├── Makefile.am ├── README ├── cronchk.sh ├── privmsg-log.pl ├── dircproxy.spec └── log.pl ├── crypt ├── .cvsignore ├── Makefile.am └── main.c ├── doc ├── .cvsignore ├── CTCPSPEC ├── DCCSPEC ├── Makefile.am ├── PROTOCOL └── dircproxy-crypt.1 ├── getopt ├── .cvsignore ├── Makefile.am ├── getopt.h └── getopt1.c ├── src ├── .cvsignore ├── memdebug.c ├── Makefile.am ├── dcc_send.h ├── cfgfile.h ├── match.h ├── stringex.h ├── dcc_chat.h ├── irc_string.h ├── timers.h ├── irc_server.h ├── stringex.c ├── logo.h ├── memdebug.h ├── sprintf.h ├── dns.h ├── irc_prot.h ├── match.c ├── net.h ├── irc_string.c ├── irc_log.h ├── dcc_net.h ├── irc_client.h ├── dcc_chat.c ├── timers.c ├── dcc_send.c ├── irc_net.h ├── help.h ├── irc_prot.c ├── dcc_net.c ├── dns.c └── irc_net.c ├── Makefile.am ├── AUTHORS.map ├── autogen.sh ├── acinclude.m4 ├── HACKING ├── TODO ├── AUTHORS ├── README.inetd ├── RELEASING ├── configure.ac ├── README.ssl ├── INSTALL ├── README.dcc-via-ssh ├── README ├── NEWS ├── install-sh └── missing /.cvsignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /conf/.cvsignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /contrib/.cvsignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crypt/.cvsignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/.cvsignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /getopt/.cvsignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/.cvsignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/CTCPSPEC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/dircproxy/master/doc/CTCPSPEC -------------------------------------------------------------------------------- /doc/DCCSPEC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/dircproxy/master/doc/DCCSPEC -------------------------------------------------------------------------------- /src/memdebug.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/dircproxy/master/src/memdebug.c -------------------------------------------------------------------------------- /conf/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to produce Makefile.in 2 | 3 | pkgdata_DATA = \ 4 | dircproxyrc.sample 5 | 6 | EXTRA_DIST = \ 7 | $(pkgdata_DATA) 8 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to produce Makefile.in 2 | 3 | man_MANS = \ 4 | dircproxy.1 \ 5 | dircproxy-crypt.1 6 | 7 | EXTRA_DIST = \ 8 | $(man_MANS) 9 | -------------------------------------------------------------------------------- /getopt/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to produce Makefile.in 2 | 3 | noinst_LIBRARIES = \ 4 | libgetopt.a 5 | 6 | libgetopt_a_SOURCES = \ 7 | getopt.c \ 8 | getopt.h \ 9 | getopt1.c 10 | -------------------------------------------------------------------------------- /contrib/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to produce Makefile.in 2 | 3 | pkgdata_DATA = \ 4 | log.pl \ 5 | privmsg-log.pl \ 6 | cronchk.sh 7 | 8 | EXTRA_DIST = \ 9 | README \ 10 | dircproxy.spec \ 11 | $(pkgdata_DATA) 12 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to produce Makefile.in 2 | 3 | EXTRA_DIST = \ 4 | FAQ \ 5 | README.inetd \ 6 | README.dcc-via-ssh 7 | 8 | SUBDIRS = \ 9 | conf \ 10 | contrib \ 11 | getopt \ 12 | crypt \ 13 | doc \ 14 | src 15 | -------------------------------------------------------------------------------- /crypt/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to produce Makefile.in 2 | 3 | AM_CPPFLAGS = -I$(top_srcdir) 4 | 5 | bin_PROGRAMS = \ 6 | dircproxy-crypt 7 | 8 | dircproxy_crypt_SOURCES = \ 9 | main.c 10 | 11 | dircproxy_crypt_LDADD = \ 12 | ../getopt/libgetopt.a 13 | -------------------------------------------------------------------------------- /AUTHORS.map: -------------------------------------------------------------------------------- 1 | keybuk:'Scott James Remnant ' 2 | scott:'Scott James Remnant ' 3 | mazpe:'Lester A. Mesa ' 4 | fharvey:'Francois Harvey ' 5 | bear:'Mike Taylor ' 6 | noel.w8tvi:'Noel Shrum ' 7 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # autogen.sh for dircproxy 3 | #Copyright (C) 2008-2009 Noel Shrum 4 | # Francois Harvey 5 | 6 | 7 | if [ -f ./configure ]; then 8 | echo "No need to run autogen.sh, run autoreconf" 9 | else 10 | aclocal 11 | autoheader 12 | automake --add-missing --copy 13 | autoconf 14 | ./configure --enable-maintainer-mode ${1+"$@"} 15 | fi 16 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to produce Makefile.in 2 | 3 | AM_CPPFLAGS = \ 4 | -I$(top_srcdir) -DSYSCONFDIR="\"${sysconfdir}\"" 5 | 6 | bin_PROGRAMS = \ 7 | dircproxy 8 | 9 | dircproxy_SOURCES = \ 10 | main.c \ 11 | dircproxy.h \ 12 | irc_net.c irc_net.h \ 13 | irc_client.c irc_client.h logo.h help.h \ 14 | irc_server.c irc_server.h \ 15 | irc_prot.c irc_prot.h \ 16 | irc_log.c irc_log.h \ 17 | irc_string.c irc_string.h \ 18 | dcc_net.c dcc_net.h \ 19 | dcc_chat.c dcc_chat.h \ 20 | dcc_send.c dcc_send.h \ 21 | cfgfile.c cfgfile.h \ 22 | timers.c timers.h \ 23 | dns.c dns.h \ 24 | net.c net.h \ 25 | match.c match.h \ 26 | stringex.c stringex.h \ 27 | sprintf.c sprintf.h \ 28 | memdebug.c memdebug.h 29 | 30 | dircproxy_LDADD = \ 31 | ../getopt/libgetopt.a 32 | -------------------------------------------------------------------------------- /src/dcc_send.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000,2001,2002,2003 Scott James Remnant . 3 | * 4 | * dcc_send.h 5 | * -- 6 | * @(#) $Id: dcc_send.h,v 1.4 2002/12/29 21:30:11 scott Exp $ 7 | * 8 | * This file is distributed according to the GNU General Public 9 | * License. For full details, read the top of 'main.c' or the 10 | * file called COPYING that was distributed with this code. 11 | */ 12 | 13 | #ifndef __DIRCPROXY_DCC_SEND_H 14 | #define __DIRCPROXY_DCC_SEND_H 15 | 16 | /* required includes */ 17 | #include "dcc_net.h" 18 | 19 | /* functions */ 20 | extern void dccsend_connected(struct dccproxy *, int); 21 | extern void dccsend_connectfailed(struct dccproxy *, int, int); 22 | extern void dccsend_accepted(struct dccproxy *); 23 | 24 | #endif /* __DIRCPROXY_DCC_SEND_H */ 25 | -------------------------------------------------------------------------------- /acinclude.m4: -------------------------------------------------------------------------------- 1 | # DIP_NET 2 | # Borrowed from xiph.org xiph_net.m4 3 | # Perform tests required by the net module 4 | AC_DEFUN([DIP_NET], 5 | [dnl 6 | AC_CHECK_HEADERS([sys/select.h sys/uio.h]) 7 | 8 | # These tests are ordered based on solaris 8 tests 9 | AC_SEARCH_LIBS([sethostent], [nsl], 10 | [AC_DEFINE([HAVE_SETHOSTENT], [1], 11 | [Define if you have the sethostent function])]) 12 | AC_SEARCH_LIBS([getnameinfo], [socket], 13 | [AC_DEFINE([HAVE_GETNAMEINFO], [1], 14 | [Define if you have the getnameinfo function])]) 15 | AC_CHECK_FUNCS([endhostent getaddrinfo inet_aton writev]) 16 | 17 | # Irix defines INET_PTON but not sockaddr_storage! 18 | AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family], 19 | [AC_CHECK_FUNCS([inet_pton])],, 20 | [#include 21 | #include ]) 22 | ]) 23 | -------------------------------------------------------------------------------- /src/cfgfile.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * cfgfile.h 11 | * -- 12 | * @(#) $Id: cfgfile.h,v 1.7 2002/12/29 21:30:11 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_CFGFILE_H 20 | #define __DIRCPROXY_CFGFILE_H 21 | 22 | /* functions */ 23 | extern int cfg_read(const char *, char **, char **, struct globalvars *); 24 | 25 | #endif /* __DIRCPROXY_CFGFILE_H */ 26 | -------------------------------------------------------------------------------- /src/match.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * match.h 11 | * -- 12 | * @(#) $Id: match.h,v 1.4 2002/12/29 21:30:12 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_MATCH_H 20 | #define __DIRCPROXY_MATCH_H 21 | 22 | /* functions */ 23 | extern int strmatch(const char *, const char *); 24 | extern int strcasematch(const char *, const char *); 25 | 26 | #endif /* __DIRCPROXY_MATCH_H */ 27 | -------------------------------------------------------------------------------- /HACKING: -------------------------------------------------------------------------------- 1 | Hacking dircproxy 2 | ----------------- 3 | 4 | If you want to hack on dircproxy, it will make your life easier to have 5 | the following packages installed: 6 | 7 | GNU autoconf 2.5x 8 | GNU automake 1.9.x 9 | 10 | 11 | Hacker's configure options 12 | -------------------------- 13 | 14 | '--enable-debug' 15 | Run on the foreground and output a log of debugging information 16 | about what dircproxy is doing. 17 | 18 | '--enable-maintainer-mode' 19 | Causes the various autotool-generated files to be automatically 20 | regenerated if you modify their sources. 21 | 22 | 23 | dircproxy is distributed according to the GNU General Public License. 24 | See the file COPYING for details. 25 | 26 | Copyright (C) 2000-2003 Scott James Remnant 27 | 28 | Copyright (C) 2004-2008 Francois Harvey 29 | 30 | Copyright (C) 2008-2009 Noel Shrum 31 | Francois Harvey 32 | 33 | -------------------------------------------------------------------------------- /src/stringex.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * stringex.h 11 | * -- 12 | * @(#) $Id: stringex.h,v 1.4 2002/12/29 21:30:12 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_STRINGEX_H 20 | #define __DIRCPROXY_STRINGEX_H 21 | 22 | /* structure to hold a list of strings */ 23 | struct strlist { 24 | char *str; 25 | 26 | struct strlist *next; 27 | }; 28 | 29 | /* functions */ 30 | extern char *strlwr(char *); 31 | extern char *strupr(char *); 32 | 33 | #endif /* __DIRCPROXY_STRINGEX_H */ 34 | -------------------------------------------------------------------------------- /src/dcc_chat.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * dcc_chat.h 11 | * -- 12 | * @(#) $Id: dcc_chat.h,v 1.6 2002/12/29 21:30:11 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_DCC_CHAT_H 20 | #define __DIRCPROXY_DCC_CHAT_H 21 | 22 | /* required includes */ 23 | #include "dcc_net.h" 24 | 25 | /* functions */ 26 | extern void dccchat_connected(struct dccproxy *, int); 27 | extern void dccchat_connectfailed(struct dccproxy *, int, int); 28 | extern void dccchat_accepted(struct dccproxy *); 29 | 30 | #endif /* __DIRCPROXY_DCC_CHAT_H */ 31 | -------------------------------------------------------------------------------- /src/irc_string.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * irc_string.h 11 | * -- 12 | * @(#) $Id: irc_string.h,v 1.5 2002/12/29 21:30:12 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_IRC_STRING_H 20 | #define __DIRCPROXY_IRC_STRING_H 21 | 22 | /* required includes */ 23 | #include "match.h" 24 | 25 | /* functions */ 26 | extern char *irc_strlwr(char *); 27 | extern char *irc_strupr(char *); 28 | extern int irc_strcasecmp(const char *, const char *); 29 | extern int irc_strcasematch(const char *, const char *); 30 | 31 | #endif /* __DIRCPROXY_STRINGEX_H */ 32 | -------------------------------------------------------------------------------- /contrib/README: -------------------------------------------------------------------------------- 1 | Contributed and unsupported extras 2 | ---------------------------------- 3 | 4 | ------------------------------------------------------- 5 | WARNING: FILE IN THIS DIR WAS NOT TESTED IN THE 1.2.0 BRANCH 6 | ------------------------------------------------------- 7 | 8 | 9 | These files are either contributed by dircproxy users, or useful to dircproxy users but not actually part of dircproxy. 10 | 11 | 12 | cronchk.sh script to run from crontab to check whether dircproxy is 13 | running or not, and restart it if necessary 14 | 15 | log.pl *_log_program script to send a mail on certain words or 16 | messages from certain people 17 | 18 | privmsg-log.pl other_log_program to log private messages to files named after 19 | the nickname of the sender (rather than all to the same file) 20 | 21 | 22 | Copyright (C) 2000-2003 Scott James Remnant 23 | 24 | Copyright (C) 2004-2008 Francois Harvey 25 | 26 | Copyright (C) 2008-2009 Noel Shrum 27 | Francois Harvey 28 | 29 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Roadmap Post-1.2.0 2 | ================== 3 | 4 | 1.2.x - fixe bug, listen user complain, add small feature (2005-2006) 5 | 6 | 7 | 1.3.x - (need a little explaination) (2006-) 8 | dircproxy is, hum, a large chunk of cryptic C code, with no dependency 9 | but full of file/hack that doesn't do a thing about IRC. 10 | 11 | * Move all the IRC stuff in a separate lib, we have already a very good 12 | C irc stuff handler, both server side, and client side. 13 | This should clean the main dircproxy source code 14 | 15 | * The main core of dircproxy should be more clean (not to deal with a 16 | lot of detail (config file, log format, irc, etc.. ) 17 | 18 | * A new config file ! work in cfgfile.c is a painfull 19 | Support /get /set command to modify option on the fly 20 | 21 | * Support new log format native (text) but also sql (sqlite/mysql), this 22 | will open the door for : 23 | /DIRCPROXY RECALL channel="#dircproxy" AND msg LIKE "*version*" 24 | Also a small web interface can be coded 25 | 26 | * Rewrite it in VB dot net (just kidding) 27 | 28 | 1.4.x 29 | * Take over the word 30 | -------------------------------------------------------------------------------- /src/timers.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * timers.h 11 | * -- 12 | * @(#) $Id: timers.h,v 1.5 2002/12/29 21:30:12 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_TIMERS_H 20 | #define __DIRCPROXY_TIMERS_H 21 | 22 | /* handy defines */ 23 | #define TIMER_FUNCTION(_FUNC) ((void (*)(void *, void *)) _FUNC) 24 | 25 | /* functions */ 26 | extern int timer_exists(void *, const char *); 27 | extern char *timer_new(void *, const char *, unsigned long, 28 | void (*)(void *, void *), void *); 29 | extern int timer_del(void *, char *); 30 | extern int timer_delall(void *); 31 | extern int timer_poll(void); 32 | extern void timer_flush(void); 33 | 34 | #endif /* __DIRCPROXY_TIMERS_H */ 35 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Authors and Acknowledgments 2 | ---------------------------- 3 | 4 | dircproxy is currently maintained by : 5 | * Francois Harvey 6 | * Noel Shrum 7 | 8 | dircproxy was originally written by Scott James Remnant , 9 | with the occasional patch from the odd random individual. 10 | 11 | Thanks to all contributor : 12 | Gabor Nyeki - 005 initial support (IRCNET Bounce) 13 | van Heusden - binding to local port 14 | Ryan Tolboom - DCC Resume in capture mode. 15 | Stephen Cope - Original Documentation 16 | Mike Taylor - Lot of patch and help 17 | brendan at kublai.com - IPV6 Support 18 | Tilman Sauerbeck - Patch 19 | acklen, W8TVI and the folks on #dircproxy (freenode) - User support 20 | 21 | If you have contributed any major patches or enhancements, and you 22 | want to be credited for it, then just nag me to add you to this file. 23 | 24 | Copyright (C) 2000-2003 Scott James Remnant 25 | 26 | Copyright (C) 2004-2008 Francois Harvey 27 | 28 | Copyright (C) 2008-2009 Noel Shrum 29 | Francois Harvey 30 | -------------------------------------------------------------------------------- /src/irc_server.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * irc_server.h 11 | * -- 12 | * @(#) $Id: irc_server.h,v 1.8 2002/12/29 21:30:12 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_IRC_SERVER_H 20 | #define __DIRCPROXY_IRC_SERVER_H 21 | 22 | /* required includes */ 23 | #include "irc_net.h" 24 | 25 | /* functions */ 26 | extern int ircserver_connect(struct ircproxy *); 27 | extern int ircserver_close_sock(struct ircproxy *); 28 | extern int ircserver_connectagain(struct ircproxy *); 29 | extern void ircserver_resetidle(struct ircproxy *); 30 | extern int ircserver_send_command(struct ircproxy *, const char *, const char *, 31 | ...); 32 | 33 | #endif /* __DIRCPROXY_IRC_SERVER_H */ 34 | -------------------------------------------------------------------------------- /contrib/cronchk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Script to run from crontab to check whether dircproxy is still running, 3 | # and if not, restart it 4 | # 5 | # You will need to set the 'pid_file' option in your .dircproxyrc 6 | # 7 | # To use, set the following in crontab 8 | # */10 * * * * cronchk.sh 9 | # or 10 | # */10 * * * * cronchk.sh /path/to/dircproxyrc 11 | 12 | # command to run dircproxy 13 | DIRCPROXY=dircproxy 14 | 15 | # config file can be specified as the first argument 16 | CONFFILE=$HOME/.dircproxyrc 17 | if test -n "$1"; then 18 | CONFFILE=$1 19 | fi 20 | 21 | # look for the pid_file directive 22 | PIDFILE=`grep ^pid_file $CONFFILE | sed 's/^pid_file[ "]*//' | sed 's/"*$//'` 23 | PIDFILE=`eval echo \`echo $PIDFILE | sed 's/^~/$HOME/'\`` 24 | if test -n "$PIDFILE" -a "$PIDFILE" != "none"; then 25 | RUNNING=no 26 | 27 | if test -r "$PIDFILE"; then 28 | if kill -0 `cat $PIDFILE` > /dev/null 2>&1; then 29 | RUNNING=yes 30 | else 31 | echo "PID file, but no dircproxy. :(" 32 | fi 33 | else 34 | echo "No PID file" 35 | fi 36 | 37 | if test "$RUNNING" = "no"; then 38 | echo "Restarting dircproxy" 39 | $DIRCPROXY 40 | fi 41 | else 42 | echo "Couldn't locate pid_file directive in config file $CONFFILE" 43 | exit 1 44 | fi 45 | -------------------------------------------------------------------------------- /src/stringex.c: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * stringex.c 11 | * - Case conversion functions 12 | * -- 13 | * @(#) $Id: stringex.c,v 1.4 2002/12/29 21:30:12 scott Exp $ 14 | * 15 | * This file is distributed according to the GNU General Public 16 | * License. For full details, read the top of 'main.c' or the 17 | * file called COPYING that was distributed with this code. 18 | */ 19 | 20 | #include 21 | 22 | #include 23 | #include "stringex.h" 24 | 25 | /* Changes the case of a string to lowercase */ 26 | char *strlwr(char *str) { 27 | char *c; 28 | 29 | c = str; 30 | while (*c) { 31 | *c = tolower(*c); 32 | c++; 33 | } 34 | 35 | return str; 36 | } 37 | 38 | /* Changes the case of a string to uppercase */ 39 | char *strupr(char *str) { 40 | char *c; 41 | 42 | c = str; 43 | while (*c) { 44 | *c = toupper(*c); 45 | c++; 46 | } 47 | 48 | return str; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/logo.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * logo.h 11 | * -- 12 | * @(#) $Id: logo.h,v 1.4 2002/12/29 21:30:12 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_LOGO_H 20 | #define __DIRCPROXY_LOGO_H 21 | 22 | /* static array to hold the logo */ 23 | static char *logo[] = { 24 | " _ _ w e l c o m e t o ", 25 | " __| (_)_ __ ___ _ __ _ __ _____ ___ _ ", 26 | " / _` | | '__/ __| '_ \\| '__/ _ \\ \\/ / | | |", 27 | "| (_| | | | | (__| |_) | | | (_) > <| |_| |", 28 | " \\__,_|_|_| \\___| .__/|_| \\___/_/\\_\\\\__, |", 29 | " |_| |___/ ", 30 | " http://dircproxy.googlecode.com/ ", 31 | 0 32 | }; 33 | 34 | /* static string to use as format for VERSION */ 35 | #ifdef SSL 36 | static char *verstr = " %s SSL"; 37 | #else /* SSL */ 38 | static char *verstr = " %s"; 39 | #endif /* SSL */ 40 | 41 | #endif /* __DIRCPROXY_LOGO_H */ 42 | -------------------------------------------------------------------------------- /src/memdebug.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * memdebug.h 11 | * -- 12 | * @(#) $Id: memdebug.h,v 1.5 2002/12/29 21:30:12 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_MEMDEBUG_H 20 | #define __DIRCPROXY_MEMDEBUG_H 21 | 22 | /* required includes */ 23 | #include 24 | 25 | /* replace standard functions with replacements wrapped around debug */ 26 | #ifdef DEBUG_MEMORY 27 | #undef malloc 28 | #undef calloc 29 | #undef free 30 | #undef realloc 31 | #define malloc(SIZE) mem_malloc(SIZE, __FILE__, __LINE__) 32 | #define calloc(NMEMB, SIZE) mem_malloc(NMEMB * SIZE, __FILE__, __LINE__) 33 | #define free(PTR) mem_realloc(PTR, 0, __FILE__, __LINE__) 34 | #define realloc(PTR, SIZE) mem_realloc(PTR, SIZE, __FILE__, __LINE__) 35 | #endif /* DEBUG_MEMORY */ 36 | 37 | /* functions */ 38 | extern void *mem_malloc(size_t, char *, int); 39 | extern void *mem_realloc(void *, size_t, char *, int); 40 | extern void mem_report(const char *); 41 | 42 | #endif /* __DIRCPROXY_MEMDEBUG_H */ 43 | -------------------------------------------------------------------------------- /src/sprintf.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * sprintf.h 11 | * -- 12 | * @(#) $Id: sprintf.h,v 1.8 2002/12/29 21:30:12 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_SPRINTF_H 20 | #define __DIRCPROXY_SPRINTF_H 21 | 22 | /* required includes */ 23 | #include 24 | 25 | /* functions */ 26 | #ifdef DEBUG_MEMORY 27 | #define x_sprintf(...) xx_sprintf(__FILE__, __LINE__, __VA_ARGS__) 28 | #define x_vsprintf(FMT, LIST) xx_vsprintf(__FILE__, __LINE__, FMT, LIST) 29 | #define x_strdup(STR) xx_strdup(__FILE__, __LINE__, STR) 30 | extern char *xx_sprintf(char *, int, const char *, ...); 31 | extern char *xx_vsprintf(char *, int, const char *, va_list); 32 | extern char *xx_strdup(char *, int, const char *); 33 | #else /* DEBUG_MEMORY */ 34 | /* Not debugging memory, run normally */ 35 | extern char *x_sprintf(const char *, ...); 36 | extern char *x_vsprintf(const char *, va_list); 37 | extern char *x_strdup(const char *); 38 | #endif /* DEBUG_MEMORY */ 39 | 40 | #endif /* __DIRCPROXY_SPRINTF_H */ 41 | -------------------------------------------------------------------------------- /src/dns.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * dns.h 11 | * -- 12 | * @(#) $Id: dns.h,v 1.7 2002/12/29 21:30:11 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_DNS_H 20 | #define __DIRCPROXY_DNS_H 21 | 22 | /* required includes */ 23 | #include 24 | #include 25 | #include 26 | 27 | #include "net.h" 28 | 29 | /* handy defines */ 30 | #define DNS_MAX_HOSTLEN 256 31 | 32 | typedef void (*dns_fun_t)(void *, void *, const char *, const char *); 33 | 34 | /* functions */ 35 | extern int dns_endrequest(pid_t, int); 36 | extern int dns_delall(void *); 37 | extern void dns_flush(void); 38 | extern int dns_addrfromhost(void *, void *, const char *, dns_fun_t); 39 | extern int dns_hostfromaddr(void *, void *, const char *, dns_fun_t); 40 | extern int dns_filladdr(void *, const char *, const char *, 41 | SOCKADDR *, dns_fun_t); 42 | extern int dns_portfromserv(const char *); 43 | extern char *dns_servfromport(int); 44 | 45 | extern int dns_getip(const char *, char *); 46 | extern int dns_getname(const char *, char *, int); 47 | #endif /* __DIRCPROXY_DNS_H */ 48 | -------------------------------------------------------------------------------- /contrib/privmsg-log.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # Logs private messages to seperate files. 3 | # 4 | # To use, set the following in dircproxyrc: 5 | # other_log_program "/path/to/privmsg-log.pl" 6 | # 7 | 8 | use vars qw/$logdir/; 9 | use strict; 10 | 11 | # Directory to store files in 12 | $logdir = '/tmp'; 13 | 14 | 15 | #------------------------------------------------------------------------------# 16 | 17 | # The first argument to this script is the source of the text. Its in the 18 | # following formats 19 | # 20 | # -dircproxy- 21 | # Notice from dircproxy 22 | # 23 | # -servername- 24 | # Notice from a server 25 | # 26 | # 27 | # Private message from a person 28 | # 29 | # -nick!username@host- 30 | # Notice from a person 31 | # 32 | # [nick!username@host] 33 | # Unfiltered CTCP message (usually an ACTION) from a person 34 | # 35 | 36 | my $source = shift(@ARGV); 37 | die "No source given by dircproxy" unless $source && length $source; 38 | 39 | my $nickname; 40 | if ($source =~ /^[<-\[]([^!]*)![^\@]*\@.*[>-\]]$/) { 41 | $nickname = $1; 42 | } else { 43 | # Not a private message, don't want it 44 | exit 0; 45 | } 46 | 47 | 48 | #------------------------------------------------------------------------------# 49 | 50 | # The second argument to this script is who it was to (your nickname or 51 | # a channel name) 52 | 53 | my $dest = shift(@ARGV); 54 | if ($dest =~ /^#/) { 55 | # A channel message, don't want it 56 | exit 0; 57 | } 58 | 59 | 60 | #------------------------------------------------------------------------------# 61 | 62 | # The text to log is on the standard input. 63 | 64 | my $text = ; 65 | die "No text given by dircproxy" unless $text && length $text; 66 | 67 | 68 | #------------------------------------------------------------------------------# 69 | 70 | open LOGFILE, ">>$logdir/$nickname"; 71 | print LOGFILE $source . " " . $text; 72 | close LOGFILE; 73 | -------------------------------------------------------------------------------- /README.inetd: -------------------------------------------------------------------------------- 1 | Running dircproxy from inetd 2 | ---------------------------- 3 | 4 | If you are so inclined, you can run dircproxy from the standard 5 | UNIX inetd daemon. This means you can do things like wrap it with 6 | tcpd etc and add all your own perverse security restrictions on top. 7 | However you loose the automatic ability to detach and reattach to 8 | your session, which makes it slightly more inconvenient to use. 9 | 10 | 11 | To run from inetd add a line to /etc/services for the port you 12 | want to listen on, and give it a service name of "dircproxy". 13 | This is actually good practice anyway. 14 | 15 | dircproxy 57000/tcp # Detachable IRC Proxy 16 | 17 | 18 | Now add a line to /etc/inetd.conf for dircproxy. You'll need to 19 | decide a username to run dircproxy as, "nobody" will probably do, 20 | don't run dircproxy as "root" unless you plan to use the 21 | "switch_user" configuration directive! Also change the PATH/TO 22 | to point to where you installed dircproxy. The -I parameter tells 23 | it its running from inetd. You can specify any other options here, 24 | such as to specify the configuration file (dircproxy will only 25 | check the system-wide configuration file when running under inetd). 26 | 27 | dircproxy stream tcp nowait USERNAME /PATH/TO/dircproxy dircproxy -I 28 | 29 | 30 | You can connect to it as normal, however when you disconnect you will 31 | be disconnected from IRC too, and won't be able to reattach to your 32 | session. To keep your session connected use the /DIRCPROXY PERSIT 33 | command. This will tell you which port you can reconnect to your 34 | session at. 35 | 36 | 37 | Copyright (C) 2000-2003 Scott James Remnant 38 | 39 | Copyright (C) 2004-2008 Francois Harvey 40 | 41 | Copyright (C) 2008-2009 Noel Shrum 42 | Francois Harvey 43 | 44 | -------------------------------------------------------------------------------- /src/irc_prot.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * irc_prot.h 11 | * -- 12 | * @(#) $Id: irc_prot.h,v 1.8 2002/12/29 21:30:12 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_IRC_PROT_H 20 | #define __DIRCPROXY_IRC_PROT_H 21 | 22 | /* required includes */ 23 | #include "stringex.h" 24 | 25 | /* structure defining where a irc message came from */ 26 | struct ircsource { 27 | char *name; 28 | char *username; /* Not server */ 29 | char *hostname; /* Not server */ 30 | char *fullname; 31 | char *orig; 32 | 33 | int type; 34 | }; 35 | 36 | /* an irc message */ 37 | struct ircmessage { 38 | struct ircsource src; 39 | char *cmd; 40 | char **params; 41 | int numparams; 42 | 43 | char *orig; 44 | char **paramstarts; 45 | }; 46 | 47 | /* a ctcp message */ 48 | struct ctcpmessage { 49 | char *cmd; 50 | char **params; 51 | int numparams; 52 | 53 | char *orig; 54 | char **paramstarts; 55 | }; 56 | 57 | /* types of ircsource */ 58 | #define IRC_PEER 0x0 59 | #define IRC_SERVER 0x1 60 | #define IRC_USER 0x2 61 | #define IRC_EITHER 0x3 62 | 63 | /* functions */ 64 | extern int ircprot_parsemsg(const char *, struct ircmessage *); 65 | extern void ircprot_freemsg(struct ircmessage *); 66 | extern void ircprot_stripctcp(const char *, char **, struct strlist **); 67 | extern int ircprot_parsectcp(const char *, struct ctcpmessage *); 68 | extern void ircprot_freectcp(struct ctcpmessage *); 69 | extern char *ircprot_sanitize_username(const char *); 70 | 71 | #endif /* __DIRCPROXY_IRC_PROT_H */ 72 | -------------------------------------------------------------------------------- /contrib/dircproxy.spec: -------------------------------------------------------------------------------- 1 | Summary: irc proxy 2 | Name: dircproxy 3 | %define branch 1.2 4 | %define version %{branch}.0 5 | %define location /usr 6 | Version: %{version} 7 | Release: 1 8 | Copyright: GPL 9 | Group: Applications/Internet 10 | URL: http://dircproxy.googlecode.com/ 11 | Source: http://dircproxy.googlecode.com/files/dircproxy-%{version}.tar.gz 12 | BuildRoot: /var/tmp/%{name}-root 13 | Packager: Hollis Blanchard 14 | 15 | %description 16 | dircproxy is an IRC proxy server designed for people who use IRC from lots of 17 | different workstations or clients, but wish to remain connected and see what 18 | they missed while they were away. You connect to IRC through dircproxy, and it 19 | keeps you connected to the server, even after you detach your client from it. 20 | While you're detached, it logs channel and private messages as well as 21 | important events, and when you reattach it'll let you know what you missed. 22 | 23 | %prep 24 | %setup 25 | 26 | %build 27 | CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{location} 28 | make 29 | 30 | %install 31 | rm -rf $RPM_BUILD_ROOT 32 | mkdir -p $RPM_BUILD_ROOT/%{location}/bin 33 | mkdir -p $RPM_BUILD_ROOT/%{location}/share/dircproxy 34 | mkdir -p $RPM_BUILD_ROOT/%{location}/man/man1/ 35 | 36 | install src/dircproxy $RPM_BUILD_ROOT/%{location}/bin 37 | install crypt/dircproxy-crypt $RPM_BUILD_ROOT/%{location}/bin 38 | install conf/dircproxyrc $RPM_BUILD_ROOT/%{location}/share/dircproxy/ 39 | install contrib/log.pl $RPM_BUILD_ROOT/%{location}/share/dircproxy/ 40 | install doc/dircproxy-crypt.1 $RPM_BUILD_ROOT/%{location}/man/man1/ 41 | install doc/dircproxy.1 $RPM_BUILD_ROOT/%{location}/man/man1/ 42 | 43 | %clean 44 | rm -rf $RPM_BUILD_ROOT 45 | 46 | %files 47 | %defattr(-,root,root) 48 | %{location}/bin/dircproxy 49 | %{location}/bin/dircproxy-crypt 50 | %{location}/share/dircproxy/dircproxyrc 51 | %{location}/share/dircproxy/log.pl 52 | %{location}/man/man1/dircproxy-crypt.1* 53 | %{location}/man/man1/dircproxy.1* 54 | %doc AUTHORS COPYING ChangeLog FAQ INSTALL NEWS PROTOCOL README* TODO 55 | -------------------------------------------------------------------------------- /src/match.c: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * match.c 11 | * - wildcard matching 12 | * 13 | * I actually figured this out and wrote it myself. Unforunately 14 | * its a lot smaller than anyone elses that I know of, which worries 15 | * me slightly :) - But it seems to work 16 | * -- 17 | * @(#) $Id: match.c,v 1.7 2002/12/29 21:30:12 scott Exp $ 18 | * 19 | * This file is distributed according to the GNU General Public 20 | * License. For full details, read the top of 'main.c' or the 21 | * file called COPYING that was distributed with this code. 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include "sprintf.h" 29 | #include "stringex.h" 30 | #include "match.h" 31 | 32 | /* Checks whether a string matches a wildcard string. 1 = yes, 0 = no */ 33 | int strmatch(const char *str, const char *mask) { 34 | int instar; 35 | 36 | instar = 0; 37 | while (*str) { 38 | if (*mask == '*') { 39 | instar = 1; 40 | mask++; 41 | } 42 | if ((*mask == *str) || (*mask == '?')) { 43 | if (instar && strmatch(str, mask)) 44 | return 1; 45 | } else { 46 | if (!instar) 47 | return 0; 48 | } 49 | str++; 50 | if (!instar) { 51 | mask++; 52 | if (!(*mask) && *str) 53 | return 0; 54 | } 55 | } 56 | 57 | return !(*mask && (*mask != '*')); 58 | } 59 | 60 | /* Case insentively matches against wildcards */ 61 | int strcasematch(const char *str, const char *mask) { 62 | char *newstr, *newmask; 63 | int ret; 64 | 65 | newstr = strlwr(x_strdup(str)); 66 | newmask = strlwr(x_strdup(mask)); 67 | 68 | ret = strmatch(newstr, newmask); 69 | 70 | free(newstr); 71 | free(newmask); 72 | 73 | return ret; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /doc/PROTOCOL: -------------------------------------------------------------------------------- 1 | IRC protocol notes 2 | ------------------ 3 | 4 | IRC has been for a long time notoriously under-documented. 5 | The original RFC was RFC1459 ("Internet Relay Chat Protocol") and 6 | was written way back in May 1993. Since that time the IRC protocol 7 | has changed quite a bit, especially in respect to the numeric codes 8 | sent to clients by the server. 9 | 10 | These have been recently updated to the modern 2.10 IRC protocol 11 | as used by the IRCnet network. They do differ in a few places, 12 | and where they do, dircproxy follows the new RFCs. 13 | 14 | For reference, the new RFCs are as follows: 15 | 16 | RFC2810 Internet Relay Chat: Architecture 17 | RFC2811 Internet Relay Chat: Channel Management 18 | RFC2812 Internet Relay Chat: Client Protocol 19 | RFC2813 Internet Relay Chat: Server Protocol 20 | 21 | 22 | Noteworthy differences 23 | ====================== 24 | 25 | RFC1459 says that parameters 2 and 3 of the USER command should be 26 | the hostname of the client, and of the server. With the advent of 27 | DNS and ident checking etc, these have been redundant for a while. 28 | RFC2812 changes the meaning of these parameters, defining the 29 | second parameter to be a bit mask of modes to set on connection, 30 | and the third to be unused. 31 | 32 | dircproxy completely ignores the 3rd parameter, and performs an 33 | atoi() on the second. If the second isn't 0 then it assumes the 34 | client follows RFC2812 and treats the bits accordingly. 35 | 36 | dircproxy always sends "0" as the second parameter and "*" as the 37 | third to any server it connects to. 38 | 39 | 40 | Modern servers send four numerics upon connection, 001 thru 004. 41 | These provide information about the server. These were not defined 42 | in RFC1459 but are defined in RFC2812. 43 | 44 | dircproxy requires these parameters to be sent by the server so 45 | it knows when the connection is completed. All servers send them 46 | anyway, so this should not cause a problem. 47 | 48 | 49 | RFC1459 says parameters in commands can be separated by one or 50 | more spaces. RFC2812 says they are separated by only ONE space 51 | (thus allowing for empty parameters). 52 | 53 | dircproxy follows RFC2812 by default, however if this causes problems 54 | for you then define the OLD_RFC1459_PARAM_SPACE in dircproxy.h 55 | 56 | 57 | Copyright (C) 2000,2001,2002,2003 Scott James Remnant . 58 | -------------------------------------------------------------------------------- /RELEASING: -------------------------------------------------------------------------------- 1 | To remove litter: 2 | for A in . conf contrib crypt doc getopt src; do \ 3 | (cd $A; rm -rf `cat .cvsignore`; rm -rf *~); done 4 | 5 | Release checklist 6 | 7 | 1. Perform a `make maintainer-clean` and remove any litter 8 | 2. Check it compiles and runs --enable-debug 9 | 3. Perform a `make maintainer-clean` and remove any litter 10 | 4. Check it compiles and runs without any flags 11 | 5. Fix any bugs/warnings, commit them, and return to 1 12 | 6. Perform a `make maintainer-clean` and remove any litter 13 | 7. Run `cvs2cl --gmt --prune -U AUTHORS.map -l '-b'` to create new 14 | ChangeLog. If this is a non-head branch replace the "-l 'b'" with 15 | "-F BRANCH-x_x". 16 | 8. `rm ChangeLog.bak` 17 | 9. `cvs diff ChangeLog > changes.txt` 18 | 10. Edit changes.txt and undiffify it. 19 | 11. Read changes.txt and write summary.txt from it 20 | 12. Write release.txt including summary.txt after an 21 | "-----Official Summary-----" marker and blank line. 22 | 13. Edit the NEWS file, add in new version and any config/use changes 23 | 14. Adjust the Features list in the README file if necessary. This will also 24 | require the adjustment of the website's index.html.in file. 25 | 15. Any changes to INSTALL? Do them and adjust website's install.html file. 26 | 16. Do a general `cvs commit -m "Version x.x.x released."` 27 | 17. do a `cvs tag RELEASE-x_x_x` 28 | 18. do an `autogen.sh` without any flags 29 | 19. make dist 30 | 20. `gpg --armor --comment 'See http://dircproxy.securiweb.net/\ 31 | download.html for more information' --detach-sign DISTFILE` 32 | 21. `md5sum DISTFILE > DISTFILE.md5` 33 | 22. scp dist file, md5 file and asc file to tetris:~ftp/pub/dircproxy/unstable 34 | 23. Remove 'src' directory from website and replace with new version 35 | 24. Add new news item title "dircproxy x.x.x released" containing release.txt 36 | 25. Add new version to bugzilla's dircproxy product 37 | 26. Run build-site.pl to make the site carry the latest information. 38 | 27. Check the site front page, news page and download page. 39 | 28. Announce new version on freshmeat using summary.txt 40 | 29. E-mail dircproxy-announce list with release.txt making sure to sign 41 | the e-mail. 42 | 30. E-Mail lester@mazpe.net with any significant changes that could 43 | affect packaging (new files etc), making sure to sign the e-mail. 44 | 31. Update and upload the new Debian package to master 45 | 32. Edit configure.ac & contrib/dircproxy.spec and increment the version 46 | number, commit with message "CVS version now x.x.x" 47 | -------------------------------------------------------------------------------- /doc/dircproxy-crypt.1: -------------------------------------------------------------------------------- 1 | .TH dircproxy-crypt 1 "09 Jan 2009" 2 | .\"Copyright (C) 2000-2003 Scott James Remnant 3 | .\"Copyright (C) 2004-2008 Francois Harvey 4 | .\"Copyright (C) 2008-2009 Noel Shrum 5 | .\" Francois Harvey 6 | .\" 7 | .\" @(#) $Id: dircproxy-crypt.1,v 1.7 2004/04/24 09:32:26 fharvey Exp $ 8 | .\" 9 | .\" This file is distributed according to the GNU General Public 10 | .\" License. For full details, read the top of 'main.c' or the 11 | .\" file called COPYING that was distributed with this code. 12 | .SH NAME 13 | \fBdircproxy-crypt\fR \- Generate encrypted password for \fBdircproxy\fR 14 | 15 | .SH SYNOPSIS 16 | \fBdircproxy-crypt\fR 17 | [\fB-hv\fR] 18 | [\fBpassword\fR]... 19 | 20 | .SH DESCRIPTION 21 | .B dircproxy-crypt 22 | generates encrypted passwords for the 23 | .BR dircproxy (1) 24 | configuration file. These passwords are used in the '\fBpassword\fR' 25 | configuration option of a connection class, and are compared to the 26 | password you configure your IRC client to use. 27 | .PP 28 | If you do not supply any plain text passwords to encrypt on the command 29 | line then \fBdircproxy-crypt\fR, when run, will ask you for one on 30 | standard input. It will display the encrypted version of each password, 31 | created using your system's 32 | .BR crypt (3) 33 | function and a random salt, on standard output. 34 | 35 | .SH OPTIONS 36 | .TP 37 | .B -h 38 | Displays a brief help message detailing the command-line arguments, 39 | then exits. 40 | .TP 41 | .B -m 42 | Create a MD5 password hash 43 | .TP 44 | .B -v 45 | Displays the \fBdircproxy\fR version number that this version of 46 | \fBdircproxy-crypt\fR comes with, then exits. 47 | 48 | .SH SEE ALSO 49 | .BR dircproxy (1) 50 | .BR crypt (3) 51 | 52 | .SH BUGS 53 | Please submit and review bug reports at: 54 | .PP 55 | .I http://code.google.com/p/dircproxy/issues/list 56 | 57 | .SH AUTHOR 58 | Written by Scott James Remnant . 59 | 60 | Current maintainership by Noel Shrum and Francois Harvey 61 | 62 | .SH COPYRIGHT 63 | Copyright (C) 2000-2003 Scott James Remnant 64 | .PP 65 | Copyright (C) 2004-2008 Francois Harvey 66 | .PP 67 | Copyright (C) 2008-2009 Noel Shrum 68 | .PP 69 | Francois Harvey 70 | 71 | 72 | \fBdircproxy\fR is distributed under the \fIGNU General Public 73 | License\fR. 74 | -------------------------------------------------------------------------------- /src/net.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * net.h 11 | * -- 12 | * @(#) $Id: net.h,v 1.9 2002/12/29 21:30:12 scott Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_NET_H 20 | #define __DIRCPROXY_NET_H 21 | 22 | #if HAVE_CONFIG_H 23 | #include "config.h" 24 | #endif 25 | 26 | #if HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 27 | # define HAVE_IPV6 1 28 | # define SOCKADDR struct sockaddr_storage 29 | # define SOCKADDR_LEN(x) ((x)->ss_family == AF_INET ? \ 30 | sizeof(struct sockaddr_in) : \ 31 | sizeof(struct sockaddr_in6)) 32 | #else 33 | # define SOCKADDR struct sockaddr_in 34 | # define SOCKADDR_LEN(x) sizeof(struct sockaddr_in) 35 | #endif 36 | /* these are in the same place in both _in and _in6 versions */ 37 | #define SOCKADDR_FAMILY(x) ((struct sockaddr_in *)(x))->sin_family 38 | #define SOCKADDR_PORT(x) ((struct sockaddr_in *)(x))->sin_port 39 | 40 | /* Socket types */ 41 | #define SOCK_NORMAL 0x00 42 | #define SOCK_CONNECTING 0x01 43 | #define SOCK_LISTENING 0x02 44 | 45 | /* handy defines */ 46 | #define ACTIVITY_FUNCTION(_FUNC) ((void (*)(void *, int)) (_FUNC)) 47 | #define ERROR_FUNCTION(_FUNC) ((void (*)(void *, int, int)) (_FUNC)) 48 | 49 | /* functions */ 50 | extern int net_socket(int); 51 | extern void net_create(int *); 52 | extern void net_keepalive(int); 53 | extern int net_close(int *); 54 | extern int net_closeall(void); 55 | extern int net_flush(void); 56 | extern int net_hook(int, int, void *, 57 | void(*)(void *, int), void(*)(void *, int, int)); 58 | extern int net_throttle(int, long, long); 59 | extern int net_send(int, const char *, ...); 60 | extern int net_sendurgent(int, const char *, ...); 61 | extern int net_queue(int, void *, int); 62 | extern int net_gets(int, char **, const char *); 63 | extern int net_read(int, void *, int); 64 | extern int net_poll(void); 65 | 66 | extern const char *net_ntop(SOCKADDR *, char *, int); 67 | extern int net_pton(int af, const char *, void *); 68 | extern int net_filladdr(SOCKADDR *, const char *, unsigned short); 69 | 70 | #endif /* __DIRCPROXY_NET_H */ 71 | -------------------------------------------------------------------------------- /src/irc_string.c: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * irc_string.c 11 | * - Case conversion functions for IRC protocol 12 | * - Comparison and match functions for IRC protocol 13 | * -- 14 | * @(#) $Id: irc_string.c,v 1.9 2002/12/29 21:30:12 scott Exp $ 15 | * 16 | * This file is distributed according to the GNU General Public 17 | * License. For full details, read the top of 'main.c' or the 18 | * file called COPYING that was distributed with this code. 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include "match.h" 27 | #include "sprintf.h" 28 | #include "irc_string.h" 29 | 30 | /* forward declarations */ 31 | static int _irc_tolower(int); 32 | static int _irc_toupper(int); 33 | 34 | /* IRC version of tolower */ 35 | static int _irc_tolower(int c) { 36 | switch (c) { 37 | case '\\': 38 | return '|'; 39 | default: 40 | return tolower(c); 41 | } 42 | } 43 | 44 | /* IRC version of tolower */ 45 | static int _irc_toupper(int c) { 46 | switch (c) { 47 | case '|': 48 | return '\\'; 49 | default: 50 | return toupper(c); 51 | } 52 | } 53 | 54 | /* Changes the case of a string to lowercase */ 55 | char *irc_strlwr(char *str) { 56 | char *c; 57 | 58 | c = str; 59 | while (*c) { 60 | *c = _irc_tolower(*c); 61 | c++; 62 | } 63 | 64 | return str; 65 | } 66 | 67 | /* Changes the case of a string to uppercase */ 68 | char *irc_strupr(char *str) { 69 | char *c; 70 | 71 | c = str; 72 | while (*c) { 73 | *c = _irc_toupper(*c); 74 | c++; 75 | } 76 | 77 | return str; 78 | } 79 | 80 | /* Compare two irc strings, ignoring case. This is done so much, I've dropped 81 | a simple version of the strcmp algorithm here rather than doing two mallocs 82 | lowercasing etc. */ 83 | int irc_strcasecmp(const char *s1, const char *s2) { 84 | while (_irc_tolower(*s1) == _irc_tolower(*s2)) { 85 | if (!*s1) 86 | return 0; 87 | 88 | s1++; 89 | s2++; 90 | } 91 | 92 | return _irc_tolower(*s1) - _irc_tolower(*s2); 93 | } 94 | 95 | /* Match an irc string against wildcards, ignoring case */ 96 | int irc_strcasematch(const char *str, const char *mask) { 97 | char *newstr, *newmask; 98 | int ret; 99 | 100 | newstr = irc_strlwr(x_strdup(str)); 101 | newmask = irc_strlwr(x_strdup(mask)); 102 | 103 | ret = strmatch(newstr, newmask); 104 | 105 | free(newstr); 106 | free(newmask); 107 | 108 | return ret; 109 | } 110 | -------------------------------------------------------------------------------- /src/irc_log.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * irc_log.h 11 | * -- 12 | * $Id: irc_log.h,v 1.15 2003/03/03 18:06:29 scott Exp $ 13 | * 14 | * This program is free software; you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation; either version 2 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program; if not, write to the Free Software 26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 | */ 28 | 29 | #ifndef DIRCPROXY_IRC_LOG_H 30 | #define DIRCPROXY_IRC_LOG_H 31 | 32 | /* Required includes */ 33 | #include 34 | 35 | #include "irc_net.h" 36 | 37 | /* Special log destination parameters */ 38 | #define IRC_LOGFILE_ALL ((char *)-1) 39 | #define IRC_LOGFILE_SERVER ((char *)0) 40 | 41 | /* Types of event we can log */ 42 | #define IRC_LOG_NONE 0x0000 43 | #define IRC_LOG_MSG 0x0001 44 | #define IRC_LOG_NOTICE 0x0002 45 | #define IRC_LOG_ACTION 0x0004 46 | #define IRC_LOG_CTCP 0x0008 47 | #define IRC_LOG_JOIN 0x0010 48 | #define IRC_LOG_PART 0x0020 49 | #define IRC_LOG_KICK 0x0040 50 | #define IRC_LOG_QUIT 0x0080 51 | #define IRC_LOG_NICK 0x0100 52 | #define IRC_LOG_MODE 0x0200 53 | #define IRC_LOG_TOPIC 0x0400 54 | #define IRC_LOG_CLIENT 0x0800 55 | #define IRC_LOG_SERVER 0x1000 56 | #define IRC_LOG_ERROR 0x2000 57 | #define IRC_LOG_ALL 0x3fff 58 | 59 | /* Functions to initialise internal logging */ 60 | int irclog_maketempdir(IRCProxy *); 61 | int irclog_init(IRCProxy *, const char *); 62 | int irclog_open(IRCProxy *, const char *); 63 | 64 | /* Functions to clean up internal logging */ 65 | void irclog_close(IRCProxy *, const char *); 66 | void irclog_free(LogFile *); 67 | void irclog_closetempdir(IRCProxy *); 68 | 69 | /* Log a message */ 70 | int irclog_log(IRCProxy *, int, const char *, const char *, const char *, ...); 71 | 72 | /* Recall log messages from the internal log */ 73 | extern int irclog_autorecall(struct ircproxy *, const char *); 74 | extern int irclog_recall(struct ircproxy *, const char *, long, long, 75 | const char *); 76 | 77 | /* Convert numeric flags to string names and back again */ 78 | int irclog_strtoflag(const char *); 79 | const char *irclog_flagtostr(int); 80 | 81 | #endif /* !DIRCPROXY_IRC_LOG_H */ 82 | -------------------------------------------------------------------------------- /src/dcc_net.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * dcc_net.h 10 | * -- 11 | * @(#) $Id: dcc_net.h,v 1.11 2004/02/14 09:05:12 fharvey Exp $ 12 | * 13 | * This file is distributed according to the GNU General Public 14 | * License. For full details, read the top of 'main.c' or the 15 | * file called COPYING that was distributed with this code. 16 | */ 17 | 18 | #ifndef __DIRCPROXY_IRC_DCC_H 19 | #define __DIRCPROXY_IRC_DCC_H 20 | 21 | /* required includes */ 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | /* Always included after dircproxy.h, so we can do this here. */ 28 | #ifdef HAVE_INTTYPES_H 29 | #include 30 | #else /* HAVE_INTTYPES_H */ 31 | #define uint32_t unsigned long 32 | #endif /* HAVE_INTTYPES_H */ 33 | 34 | /* a proxied dcc connection */ 35 | struct dccproxy { 36 | int dead; 37 | int type; 38 | time_t start; 39 | 40 | int sender_sock; 41 | int sender_status; 42 | struct sockaddr_in sender_addr; 43 | 44 | int sendee_sock; 45 | int sendee_status; 46 | struct sockaddr_in sendee_addr; 47 | 48 | int (*notify_func)(void *, const char *, const char *); 49 | void *notify_data; 50 | char *notify_msg; 51 | 52 | /* DCC SEND only */ 53 | uint32_t bytes_sent, bytes_ackd, bytes_rcvd; 54 | char *buf; 55 | unsigned long bufsz; 56 | 57 | /* DCC SEND (Capture) only */ 58 | char *cap_filename; 59 | FILE *cap_file; 60 | uint32_t bytes_max; 61 | 62 | struct dccproxy *next; 63 | }; 64 | 65 | /* handy defines */ 66 | #define DCCN_FUNCTION(_FUNC) ((int (*)(void *, const char *, const char *)) \ 67 | _FUNC) 68 | 69 | /* types of dcc proxy */ 70 | #define DCC_CHAT 0x01 71 | #define DCC_SEND_SIMPLE 0x10 72 | #define DCC_SEND_FAST 0x20 73 | #define DCC_SEND_CAPTURE 0x40 74 | #define DCC_SEND 0x70 75 | 76 | /* states a sender can be in */ 77 | #define DCC_SENDER_NONE 0x00 78 | #define DCC_SENDER_CREATED 0x01 79 | #define DCC_SENDER_CONNECTED 0x02 80 | #define DCC_SENDER_GONE 0x04 81 | #define DCC_SENDER_ACTIVE 0x03 82 | 83 | /* states a sendee can be in */ 84 | #define DCC_SENDEE_NONE 0x00 85 | #define DCC_SENDEE_LISTENING 0x01 86 | #define DCC_SENDEE_CONNECTED 0x02 87 | #define DCC_SENDEE_ACTIVE 0x02 88 | #define DCC_SENDEE_CREATED 0x03 89 | 90 | /* functions */ 91 | extern int dccnet_new(int, long, int *, size_t, int *, 92 | struct in_addr, int, const char *, long, 93 | int (*)(void *, const char *, const char *), 94 | void *, const char *, uint32_t); 95 | extern int dccnet_expunge_proxies(void); 96 | extern void dccnet_flush(void); 97 | 98 | #endif /* __DIRCPROXY_IRC_DCC_H */ 99 | -------------------------------------------------------------------------------- /contrib/log.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # Perl script to take dircproxy log information and e-mail it to 3 | # an address if it contains certain words or is from certain people. 4 | # 5 | # To use, set the following in dircproxyrc: 6 | # chan_log_program "/path/to/log.pl" 7 | # or 8 | # other_log_program "/path/to/log.pl" 9 | # 10 | 11 | use vars qw/$mailto @match @from $sendmail/; 12 | use strict; 13 | 14 | # Address to e-mail to 15 | $mailto = 'nobody@localhost'; 16 | 17 | # Words to match on 18 | @match = ('rabbit', 'llama'); 19 | 20 | # People to always send 21 | @from = ('Joe', 'Bloggs'); 22 | 23 | # Path to sendmail 24 | $sendmail = '/usr/lib/sendmail'; 25 | 26 | 27 | #------------------------------------------------------------------------------# 28 | 29 | # The first argument to this script is the source of the text. Its in the 30 | # following formats 31 | # 32 | # -dircproxy- 33 | # Notice from dircproxy 34 | # 35 | # -servername- 36 | # Notice from a server 37 | # 38 | # 39 | # Private message from a person 40 | # 41 | # -nick!username@host- 42 | # Notice from a person 43 | # 44 | # [nick!username@host] 45 | # Unfiltered CTCP message (usually an ACTION) from a person 46 | # 47 | 48 | my $source = shift(@ARGV); 49 | die "No source given by dircproxy" unless $source && length $source; 50 | 51 | my $notice = ($source =~ /^-/ ? 1 : 0); 52 | $source =~ s/^.//; 53 | $source =~ s/.$//; 54 | 55 | my ($nickname, $username, $hostname); 56 | my $server = 0; 57 | if ($source =~ /^([^!]*)!([^\@]*)\@(.*)$/) { 58 | ($nickname, $username, $hostname) = ($1, $2, $3); 59 | } else { 60 | $nickname = $source; 61 | $server = 1 if $notice; 62 | } 63 | 64 | 65 | #------------------------------------------------------------------------------# 66 | 67 | # The second argument to this script is who it was to (your nickname or 68 | # a channel name) 69 | 70 | my $dest = shift(@ARGV); 71 | 72 | 73 | #------------------------------------------------------------------------------# 74 | 75 | # The text to log is on the standard input. 76 | 77 | my $text = ; 78 | die "No text given by dircproxy" unless $text && length $text; 79 | 80 | 81 | #------------------------------------------------------------------------------# 82 | 83 | my $mailit = 0; 84 | 85 | # Always mail server messages (including those from dircproxy) 86 | $mailit = 1 if $server; 87 | 88 | # Check the from 89 | foreach my $from (@from) { 90 | $mailit = 1 if lc($nickname) eq lc($from); 91 | } 92 | 93 | # Check the text 94 | foreach my $match (@match) { 95 | $mailit = 1 if $text =~ /$match/i; 96 | } 97 | 98 | #------------------------------------------------------------------------------# 99 | 100 | if ($mailit) { 101 | my $subject = ""; 102 | if ($server) { 103 | $subject .= "Server message"; 104 | } elsif ($notice) { 105 | $subject .= "Notice"; 106 | } else { 107 | $subject .= "Message"; 108 | } 109 | $subject .= " from " . $nickname; 110 | $subject .= " ($username\@$hostname)" unless $server; 111 | 112 | open MAILER, '|' . $sendmail . ' -t'; 113 | print MAILER "From: dircproxy\n"; 114 | print MAILER "To: $mailto\n"; 115 | print MAILER "Subject: $subject\n"; 116 | print MAILER "\n"; 117 | print MAILER "Sent to $dest\n" if $dest; 118 | print MAILER $text; 119 | close MAILER; 120 | } 121 | -------------------------------------------------------------------------------- /src/irc_client.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * irc_client.h 11 | * -- 12 | * @(#) $Id: irc_client.h,v 1.8 2004/02/15 00:56:18 bear Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_IRC_CLIENT_H 20 | #define __DIRCPROXY_IRC_CLIENT_H 21 | 22 | /* required includes */ 23 | #include "irc_net.h" 24 | #include "help.h" 25 | 26 | static char * client_commands[] = { 27 | "DIE", 28 | "DETACH", 29 | "HELP", 30 | "HOST", 31 | "JUMP", 32 | "KILL", 33 | "RECALL", 34 | "RELOAD", 35 | "MOTD", 36 | "PERSIST", 37 | "QUIT", 38 | "USERS", 39 | "SERVERS", 40 | "STATUS", 41 | "NOTIFY", 42 | "GET", 43 | "SET" 44 | }; 45 | 46 | #define I_HELP_INDEX 0 47 | #define I_HELP_INDEX_END 1 48 | #define I_HELP_DIE 2 49 | #define I_HELP_DETACH 3 50 | #define I_HELP_HOST 4 51 | #define I_HELP_JUMP 5 52 | #define I_HELP_JUMP_NEW 6 53 | #define I_HELP_KILL 7 54 | #define I_HELP_HELP 8 55 | #define I_HELP_RECALL 9 56 | #define I_HELP_RELOAD 10 57 | #define I_HELP_MOTD 11 58 | #define I_HELP_PERSIST 12 59 | #define I_HELP_QUIT 13 60 | #define I_HELP_USERS 14 61 | #define I_HELP_SERVERS 15 62 | #define I_HELP_STATUS 16 63 | #define I_HELP_NOTIFY 17 64 | #define I_HELP_GET 18 65 | #define I_HELP_SET 19 66 | 67 | static char ** command_help[] = { 68 | help_index, 69 | help_index_end, 70 | help_die, 71 | help_detach, 72 | help_host, 73 | help_jump, 74 | help_jump_new, 75 | help_kill, 76 | help_help, 77 | help_recall, 78 | help_reload, 79 | help_motd, 80 | help_persist, 81 | help_quit, 82 | help_users, 83 | help_servers, 84 | help_status, 85 | help_notify, 86 | help_get, 87 | help_set 88 | }; 89 | 90 | /* functions */ 91 | extern int ircclient_connected(struct ircproxy *); 92 | extern int ircclient_data(struct ircproxy *); 93 | extern int ircclient_change_nick(struct ircproxy *, const char *); 94 | extern int ircclient_nick_changed(struct ircproxy *, const char *); 95 | extern int ircclient_setnickname(struct ircproxy *); 96 | extern int ircclient_checknickname(struct ircproxy *); 97 | extern int ircclient_generate_nick(struct ircproxy *, const char *); 98 | extern int ircclient_change_mode(struct ircproxy *, const char *); 99 | extern int ircclient_close(struct ircproxy *); 100 | extern int ircclient_welcome(struct ircproxy *); 101 | extern int ircclient_send_numeric(struct ircproxy *, short, const char *, ...); 102 | extern int ircclient_send_notice(struct ircproxy *, const char *, ...); 103 | extern int ircclient_send_channotice(struct ircproxy *, const char *, 104 | const char *, ...); 105 | extern int ircclient_send_command(struct ircproxy *, const char *, const char *, 106 | ...); 107 | extern int ircclient_send_selfcmd(struct ircproxy *, const char *, const char *, 108 | ...); 109 | extern int ircclient_send_error(struct ircproxy *, const char *, ...); 110 | 111 | #endif /* __DIRCPROXY_IRC_CLIENT_H */ 112 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # Process this file with autoconf to produce a configure script. 2 | # $Id: configure.ac,v 1.9 2003/12/31 23:16:25 fharvey Exp $ 3 | 4 | AC_INIT([dircproxy], [1.2.0], [http://dircproxy.googlecode.com/]) 5 | AM_INIT_AUTOMAKE 6 | AM_MAINTAINER_MODE 7 | AC_COPYRIGHT([Copyright (C) 2009 Noel Shrum & Francois Harvey.]) 8 | AC_CONFIG_SRCDIR([src/dircproxy.h]) 9 | AM_CONFIG_HEADER([config.h]) 10 | 11 | # Checks for programs. 12 | AC_PROG_CC 13 | AC_PROG_INSTALL 14 | AC_PROG_AWK 15 | AC_PROG_RANLIB 16 | AC_PROG_MAKE_SET 17 | 18 | # Checks for libraries. 19 | AC_CHECK_FUNC([socket],, 20 | [AC_CHECK_LIB([socket], [socket],, 21 | [AC_MSG_WARN([couldn't find your socket() function])])]) 22 | AC_CHECK_FUNC([gethostbyname],, 23 | [AC_CHECK_LIB([nsl], [gethostbyname],, 24 | [AC_MSG_WARN([couldn't find your gethostbyname() function])])]) 25 | AC_CHECK_FUNC([crypt],, 26 | [AC_CHECK_LIB([crypt], [crypt],, 27 | [AC_MSG_WARN([couldn't find your crypt() function])])]) 28 | 29 | # Checks for header files. 30 | AC_FUNC_ALLOCA 31 | AC_HEADER_STDC 32 | AC_HEADER_SYS_WAIT 33 | AC_CHECK_HEADERS([arpa/inet.h netinet/in.h sys/param.h sys/socket.h sys/time.h \ 34 | crypt.h fcntl.h inttypes.h netdb.h stdlib.h string.h \ 35 | syslog.h unistd.h]) 36 | 37 | # Checks for typedefs, structures, and compiler characteristics. 38 | AC_C_CONST 39 | AC_TYPE_PID_T 40 | AC_TYPE_SIZE_T 41 | AC_HEADER_TIME 42 | AC_TYPE_UID_T 43 | 44 | # Checks for library functions. 45 | AC_FUNC_ERROR_AT_LINE 46 | AC_FUNC_FORK 47 | AC_FUNC_LSTAT 48 | AC_FUNC_MALLOC 49 | AC_TYPE_SIGNAL 50 | AC_FUNC_STAT 51 | AC_FUNC_STRFTIME 52 | AC_CHECK_FUNCS([alarm dup2 gethostbyaddr inet_ntoa memmove memset mkdir rmdir \ 53 | realloc select seteuid strcasecmp strchr strcspn strerror \ 54 | strncasecmp strrchr strspn strstr strtoul]) 55 | 56 | DIP_NET 57 | 58 | # Check whether to debug things 59 | AC_ARG_ENABLE([debug], AC_HELP_STRING([--enable-debug], [turn on debugging (default is NO)]), 60 | [ if test "x${enable_debug}" = "xyes"; then 61 | use_debug="y" 62 | CFLAGS="-g -Wall $CFLAGS" 63 | AC_DEFINE([DEBUG], [1], [Are we debugging?]) 64 | AC_DEFINE([DEBUG_MEMORY], [1], [Turn on expensive, but useful, memory debugging code]) 65 | fi ]) 66 | if test -z "${use_debug}"; then 67 | AC_CHECK_FUNCS([strdup vasprintf vsnprintf]) 68 | fi 69 | 70 | # Use SSL (currently OpenSSL) 71 | AC_ARG_ENABLE([ssl], AC_HELP_STRING([--enable-ssl], [Add SSL support]), 72 | [ if test "x${enable_ssl}" = "xyes"; then 73 | use_ssl="y" 74 | CFLAGS="-DSSL $CFLAGS " 75 | AC_DEFINE([SSL], [1], [Try to sniff me now]) 76 | fi ]) 77 | # if test -z "${use_ssl}"; then 78 | # AC_CHECK_FUNCS([str dup vasprintf vsnprintf]) 79 | # fi 80 | 81 | 82 | # Use of poll() can be disabled in favour of select 83 | AC_ARG_ENABLE([poll], AC_HELP_STRING([--disable-poll], [disable use of the poll() function (default is NO)]), 84 | [ if test "x${enable_poll}" = "xyes"; then 85 | : 86 | else 87 | use_poll="n" 88 | fi ]) 89 | if test -z "${use_poll}"; then 90 | AC_CHECK_FUNCS([poll]) 91 | AC_CHECK_HEADERS([poll.h sys/poll.h]) 92 | fi 93 | 94 | # Use of select() can be disabled too 95 | AC_ARG_ENABLE([select], AC_HELP_STRING([--disable-select], [disable use of the select() function (default is NO)]), 96 | [ if test "x${enable_select}" = "xyes"; then 97 | : 98 | else 99 | use_select="n" 100 | fi ]) 101 | if test -z "${use_select}"; then 102 | AC_CHECK_FUNCS([select]) 103 | fi 104 | 105 | AC_CONFIG_FILES([Makefile conf/Makefile contrib/Makefile getopt/Makefile crypt/Makefile doc/Makefile src/Makefile]) 106 | AC_OUTPUT 107 | -------------------------------------------------------------------------------- /README.ssl: -------------------------------------------------------------------------------- 1 | 2 | 3 | NO SSL IN 1.2.X RELEASE 4 | 5 | SSL IS PLANNED IN 1.3.X RELEASE 6 | 7 | 8 | -------------------------- 9 | [ Using SSL with dircproxy ] 10 | -------------------------- 11 | 12 | * DISCLAIMER : 13 | * 14 | * THIS IS AN UNSTABLE DEVELOPMENT RELEASE OF DIRCPROXY. IT HAS HIGHER 15 | * THAN USUAL RISK OF DESTROYING YOUR SYSTEM OR LOSING YOUR DATA OR 16 | * CORRUPTING YOUR BOX. 17 | * 18 | * DO NOT USE IT IF YOU DO NOT ACCEPT THE RISKS 19 | * 20 | * RESPONSABILITY OF DIRCPROXY STAFF COULD NOT BE ENGAGED IN ANY CASE 21 | 22 | 23 | What has changed in this branch 24 | =============================== 25 | 26 | This branch adds SSL support for both client-side and server-side. 27 | Both features may be used independently. 28 | 29 | o Client-side : dircproxy connects to SSL-enabled servers, allowing 30 | you to identify the IRC server you are connecting to, eventually 31 | identifying yourself to the server and securing communications with 32 | a crypted socket. 33 | o Server-side : dircproxy offers SSL services, allowing you to identify 34 | the dircproxy server you are connecting to, eventually identifying 35 | yourself to the server and securing communications with a crypted socket. 36 | 37 | These changes are useful for people worried about their talk privacy. 38 | 39 | What has been done 40 | ================== 41 | 42 | - Client-side : 43 | o Connecting to any SSL-enabled server, using the "server_ssl" var in 44 | config-file 45 | 46 | - Server-side : 47 | o Presenting the certificate to any client and allow any client to connect 48 | 49 | What needs to be done 50 | ===================== 51 | 52 | [P] = Priority [E] = Enhancement 53 | 54 | - Client-side : 55 | o [E] Checking the certificate validity (date, server name, fingerprint) 56 | o [E] Allow users to manually validate certificate 57 | o [E] Allow dircproxy to present a certificate to identify user on server 58 | 59 | - Server-side : 60 | o [P] dircproxy hangs when SSL is enabled and client connects without 61 | SSL (due to "while(SSL_accept(p->cliSSL.ssl) != 1);" in irc_net.c on 62 | line 235, need to find a smarter way to handle this) 63 | o [E] Allow user to present a certificate to identify user on server 64 | 65 | How to use dircproxy-SSL 66 | ======================== 67 | 68 | - Client-side : Add 'server_ssl yes' (without quotes) to your config file 69 | and dircproxy will connect to server using a SSL socket 70 | 71 | - Server-side : Add 'pk_file "/path/to/privkey.pem"' and 72 | 'cert_file "/path/to/cacert.pem"' (both without simple quotes) and 73 | dircproxy will present the certificate to connecting users. 74 | 75 | To generate a test certificate with OpenSSL (http://www.openssl.org/), 76 | generate a private key with "openssl genrsa -out privkey.pem 2048" then 77 | generate a self-signed certificate 78 | "openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095" 79 | 80 | * BEWARE NOT TO USE SELF-SIGNED CERTIFICATE IN PRODUCTION ENVIRONMENT * 81 | 82 | 83 | More Information 84 | ================ 85 | 86 | The dircproxy home page is at: 87 | http://code.google.com/p/dircproxy/ 88 | 89 | Please submit bug reports at: 90 | http://code.google.com/p/dircproxy/issues/list 91 | 92 | Also join us on the #dircproxy IRC channel on irc.freenode.net. 93 | 94 | dircproxy is distributed according to the GNU General Public License. 95 | See the file COPYING for details. 96 | 97 | 98 | Copyright (C) 2000-2003 Scott James Remnant 99 | 100 | Copyright (C) 2004-2008 Francois Harvey 101 | 102 | Copyright (C) 2008-2009 Noel Shrum 103 | Francois Harvey 104 | 105 | -------------------------------------------------------------------------------- /getopt/getopt.h: -------------------------------------------------------------------------------- 1 | /* Declarations for getopt. 2 | Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU General Public License as published by the 6 | Free Software Foundation; either version 2, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 17 | 18 | #ifndef _GETOPT_H 19 | #define _GETOPT_H 1 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /* For communication from `getopt' to the caller. 26 | When `getopt' finds an option that takes an argument, 27 | the argument value is returned here. 28 | Also, when `ordering' is RETURN_IN_ORDER, 29 | each non-option ARGV-element is returned here. */ 30 | 31 | extern char *optarg; 32 | 33 | /* Index in ARGV of the next element to be scanned. 34 | This is used for communication to and from the caller 35 | and for communication between successive calls to `getopt'. 36 | 37 | On entry to `getopt', zero means this is the first call; initialize. 38 | 39 | When `getopt' returns EOF, this is the index of the first of the 40 | non-option elements that the caller should itself scan. 41 | 42 | Otherwise, `optind' communicates from one call to the next 43 | how much of ARGV has been scanned so far. */ 44 | 45 | extern int optind; 46 | 47 | /* Callers store zero here to inhibit the error message `getopt' prints 48 | for unrecognized options. */ 49 | 50 | extern int opterr; 51 | 52 | /* Set to an option character which was unrecognized. */ 53 | 54 | extern int optopt; 55 | 56 | /* Describe the long-named options requested by the application. 57 | The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector 58 | of `struct option' terminated by an element containing a name which is 59 | zero. 60 | 61 | The field `has_arg' is: 62 | no_argument (or 0) if the option does not take an argument, 63 | required_argument (or 1) if the option requires an argument, 64 | optional_argument (or 2) if the option takes an optional argument. 65 | 66 | If the field `flag' is not NULL, it points to a variable that is set 67 | to the value given in the field `val' when the option is found, but 68 | left unchanged if the option is not found. 69 | 70 | To have a long-named option do something other than set an `int' to 71 | a compiled-in constant, such as set a value from `optarg', set the 72 | option's `flag' field to zero and its `val' field to a nonzero 73 | value (the equivalent single-letter option character, if there is 74 | one). For long options that have a zero `flag' field, `getopt' 75 | returns the contents of the `val' field. */ 76 | 77 | struct option 78 | { 79 | #if __STDC__ 80 | const char *name; 81 | #else 82 | char *name; 83 | #endif 84 | /* has_arg can't be an enum because some compilers complain about 85 | type mismatches in all the code that assumes it is an int. */ 86 | int has_arg; 87 | int *flag; 88 | int val; 89 | }; 90 | 91 | /* Names for the values of the `has_arg' field of `struct option'. */ 92 | 93 | #define no_argument 0 94 | #define required_argument 1 95 | #define optional_argument 2 96 | 97 | #if __STDC__ 98 | #if defined(__GNU_LIBRARY__) 99 | /* Many other libraries have conflicting prototypes for getopt, with 100 | differences in the consts, in stdlib.h. To avoid compilation 101 | errors, only prototype getopt for the GNU C library. */ 102 | extern int getopt (int argc, char *const *argv, const char *shortopts); 103 | #else /* not __GNU_LIBRARY__ */ 104 | extern int getopt (); 105 | #endif /* not __GNU_LIBRARY__ */ 106 | extern int getopt_long (int argc, char *const *argv, const char *shortopts, 107 | const struct option *longopts, int *longind); 108 | extern int getopt_long_only (int argc, char *const *argv, 109 | const char *shortopts, 110 | const struct option *longopts, int *longind); 111 | 112 | /* Internal only. Users should not call this directly. */ 113 | extern int _getopt_internal (int argc, char *const *argv, 114 | const char *shortopts, 115 | const struct option *longopts, int *longind, 116 | int long_only); 117 | #else /* not __STDC__ */ 118 | extern int getopt (); 119 | extern int getopt_long (); 120 | extern int getopt_long_only (); 121 | 122 | extern int _getopt_internal (); 123 | #endif /* not __STDC__ */ 124 | 125 | #ifdef __cplusplus 126 | } 127 | #endif 128 | 129 | #endif /* _GETOPT_H */ 130 | -------------------------------------------------------------------------------- /getopt/getopt1.c: -------------------------------------------------------------------------------- 1 | /* getopt_long and getopt_long_only entry points for GNU getopt. 2 | Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 3 | Free Software Foundation, Inc. 4 | 5 | This program is free software; you can redistribute it and/or modify it 6 | under the terms of the GNU General Public License as published by the 7 | Free Software Foundation; either version 2, or (at your option) any 8 | later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 18 | 19 | #ifdef HAVE_CONFIG_H 20 | #include "config.h" 21 | #endif 22 | 23 | #include "getopt.h" 24 | 25 | #if !__STDC__ && !defined(const) && IN_GCC 26 | #define const 27 | #endif 28 | 29 | #include 30 | 31 | /* Comment out all this code if we are using the GNU C Library, and are not 32 | actually compiling the library itself. This code is part of the GNU C 33 | Library, but also included in many other GNU distributions. Compiling 34 | and linking in this code is a waste when using the GNU C library 35 | (especially if it is a shared library). Rather than having every GNU 36 | program understand `configure --with-gnu-libc' and omit the object files, 37 | it is simpler to just do this in the source for each such file. */ 38 | 39 | #if defined (_LIBC) || !defined (__GNU_LIBRARY__) 40 | 41 | 42 | /* This needs to come after some library #include 43 | to get __GNU_LIBRARY__ defined. */ 44 | #ifdef __GNU_LIBRARY__ 45 | #include 46 | #else 47 | char *getenv (); 48 | #endif 49 | 50 | #ifndef NULL 51 | #define NULL 0 52 | #endif 53 | 54 | int 55 | getopt_long (argc, argv, options, long_options, opt_index) 56 | int argc; 57 | char *const *argv; 58 | const char *options; 59 | const struct option *long_options; 60 | int *opt_index; 61 | { 62 | return _getopt_internal (argc, argv, options, long_options, opt_index, 0); 63 | } 64 | 65 | /* Like getopt_long, but '-' as well as '--' can indicate a long option. 66 | If an option that starts with '-' (not '--') doesn't match a long option, 67 | but does match a short option, it is parsed as a short option 68 | instead. */ 69 | 70 | int 71 | getopt_long_only (argc, argv, options, long_options, opt_index) 72 | int argc; 73 | char *const *argv; 74 | const char *options; 75 | const struct option *long_options; 76 | int *opt_index; 77 | { 78 | return _getopt_internal (argc, argv, options, long_options, opt_index, 1); 79 | } 80 | 81 | 82 | #endif /* _LIBC or not __GNU_LIBRARY__. */ 83 | 84 | #ifdef TEST 85 | 86 | #include 87 | 88 | int 89 | main (argc, argv) 90 | int argc; 91 | char **argv; 92 | { 93 | int c; 94 | int digit_optind = 0; 95 | 96 | while (1) 97 | { 98 | int this_option_optind = optind ? optind : 1; 99 | int option_index = 0; 100 | static struct option long_options[] = 101 | { 102 | {"add", 1, 0, 0}, 103 | {"append", 0, 0, 0}, 104 | {"delete", 1, 0, 0}, 105 | {"verbose", 0, 0, 0}, 106 | {"create", 0, 0, 0}, 107 | {"file", 1, 0, 0}, 108 | {0, 0, 0, 0} 109 | }; 110 | 111 | c = getopt_long (argc, argv, "abc:d:0123456789", 112 | long_options, &option_index); 113 | if (c == EOF) 114 | break; 115 | 116 | switch (c) 117 | { 118 | case 0: 119 | printf ("option %s", long_options[option_index].name); 120 | if (optarg) 121 | printf (" with arg %s", optarg); 122 | printf ("\n"); 123 | break; 124 | 125 | case '0': 126 | case '1': 127 | case '2': 128 | case '3': 129 | case '4': 130 | case '5': 131 | case '6': 132 | case '7': 133 | case '8': 134 | case '9': 135 | if (digit_optind != 0 && digit_optind != this_option_optind) 136 | printf ("digits occur in two different argv-elements.\n"); 137 | digit_optind = this_option_optind; 138 | printf ("option %c\n", c); 139 | break; 140 | 141 | case 'a': 142 | printf ("option a\n"); 143 | break; 144 | 145 | case 'b': 146 | printf ("option b\n"); 147 | break; 148 | 149 | case 'c': 150 | printf ("option c with value `%s'\n", optarg); 151 | break; 152 | 153 | case 'd': 154 | printf ("option d with value `%s'\n", optarg); 155 | break; 156 | 157 | case '?': 158 | break; 159 | 160 | default: 161 | printf ("?? getopt returned character code 0%o ??\n", c); 162 | } 163 | } 164 | 165 | if (optind < argc) 166 | { 167 | printf ("non-option ARGV-elements: "); 168 | while (optind < argc) 169 | printf ("%s ", argv[optind++]); 170 | printf ("\n"); 171 | } 172 | 173 | exit (0); 174 | } 175 | 176 | #endif /* TEST */ 177 | -------------------------------------------------------------------------------- /src/dcc_chat.c: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * dcc_chat.c 11 | * - DCC chat protocol 12 | * -- 13 | * @(#) $Id: dcc_chat.c,v 1.13 2002/12/29 21:30:11 scott Exp $ 14 | * 15 | * This file is distributed according to the GNU General Public 16 | * License. For full details, read the top of 'main.c' or the 17 | * file called COPYING that was distributed with this code. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | #include "sprintf.h" 32 | #include "net.h" 33 | #include "dns.h" 34 | #include "timers.h" 35 | #include "dcc_net.h" 36 | #include "dcc_chat.h" 37 | 38 | /* forward declarations */ 39 | static void _dccchat_data(struct dccproxy *, int); 40 | static void _dccchat_error(struct dccproxy *, int, int); 41 | 42 | /* Called when we've connected to the sender */ 43 | void dccchat_connected(struct dccproxy *p, int sock) { 44 | if (sock != p->sender_sock) { 45 | error("Unexpected socket %d in dccchat_connected, expected %d", sock, 46 | p->sender_sock); 47 | net_close(&sock); 48 | return; 49 | } 50 | 51 | debug("DCC Connection succeeded"); 52 | p->sender_status |= DCC_SENDER_CONNECTED; 53 | net_hook(p->sender_sock, SOCK_NORMAL, (void *)p, 54 | ACTIVITY_FUNCTION(_dccchat_data), 55 | ERROR_FUNCTION(_dccchat_error)); 56 | 57 | if (p->sendee_status != DCC_SENDEE_ACTIVE) { 58 | net_send(p->sender_sock, "--(%s)-- Awaiting connection from remote peer\n", 59 | PACKAGE); 60 | } else { 61 | net_send(p->sendee_sock, "--(%s)-- Connected to remote peer\n", PACKAGE); 62 | } 63 | } 64 | 65 | /* Called when a connection fails */ 66 | void dccchat_connectfailed(struct dccproxy *p, int sock, int bad) { 67 | if (sock != p->sender_sock) { 68 | error("Unexpected socket %d in dccchat_connectfailed, expected %d", sock, 69 | p->sender_sock); 70 | net_close(&sock); 71 | return; 72 | } 73 | 74 | if (p->sendee_status == DCC_SENDEE_ACTIVE) 75 | net_send(p->sendee_sock, "--(%s)-- Connection to remote peer failed\n", 76 | PACKAGE); 77 | 78 | if (p->notify_func) 79 | p->notify_func(p->notify_data, p->notify_msg, 80 | "Connection to remote peer failed"); 81 | 82 | debug("DCC Connection failed"); 83 | p->sender_status &= ~(DCC_SENDER_CREATED); 84 | net_close(&(p->sender_sock)); 85 | p->dead = 1; 86 | } 87 | 88 | /* Called when the sendee has been accepted */ 89 | void dccchat_accepted(struct dccproxy *p) { 90 | net_hook(p->sendee_sock, SOCK_NORMAL, (void *)p, 91 | ACTIVITY_FUNCTION(_dccchat_data), 92 | ERROR_FUNCTION(_dccchat_error)); 93 | 94 | if (p->sender_status != DCC_SENDER_ACTIVE) { 95 | net_send(p->sendee_sock, "--(%s)-- Connecting to remote peer\n", PACKAGE); 96 | } else { 97 | net_send(p->sender_sock, "--(%s)-- Remote peer connected\n", PACKAGE); 98 | } 99 | } 100 | 101 | /* Called when we get data over a DCC link */ 102 | static void _dccchat_data(struct dccproxy *p, int sock) { 103 | char *str, *dir; 104 | int to; 105 | 106 | if (sock == p->sender_sock) { 107 | dir = "}}"; 108 | to = p->sendee_sock; 109 | 110 | if (p->sendee_status != DCC_SENDEE_ACTIVE) 111 | return; 112 | } else if (sock == p->sendee_sock) { 113 | dir = "{{"; 114 | to = p->sender_sock; 115 | 116 | if (p->sender_status != DCC_SENDER_ACTIVE) 117 | return; 118 | } else { 119 | error("Unexpected socket %d in dccchat_data, expected %d or %d", sock, 120 | p->sender_sock, p->sendee_sock); 121 | net_close(&sock); 122 | return; 123 | } 124 | 125 | str = 0; 126 | while (net_gets(sock, &str, "\n") > 0) { 127 | debug("%s '%s'", dir, str); 128 | net_send(to, "%s\n", str); 129 | free(str); 130 | } 131 | } 132 | 133 | /* Called on DCC disconnection or error */ 134 | static void _dccchat_error(struct dccproxy *p, int sock, int bad) { 135 | char *who; 136 | 137 | if (sock == p->sender_sock) { 138 | who = "Sender"; 139 | p->sender_status &= ~(DCC_SENDER_CREATED); 140 | net_close(&(p->sender_sock)); 141 | } else if (sock == p->sendee_sock) { 142 | who = "Sendee"; 143 | p->sendee_status &= ~(DCC_SENDEE_CREATED); 144 | net_close(&(p->sendee_sock)); 145 | } else { 146 | error("Unexpected socket %d in dccchat_error, expected %d or %d", sock, 147 | p->sender_sock, p->sendee_sock); 148 | net_close(&sock); 149 | return; 150 | } 151 | 152 | if (bad) { 153 | debug("Socket error with %s", who); 154 | } else { 155 | debug("%s disconnected", who); 156 | } 157 | 158 | p->dead = 1; 159 | } 160 | -------------------------------------------------------------------------------- /src/timers.c: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * timers.c 11 | * - Scheduling events 12 | * -- 13 | * @(#) $Id: timers.c,v 1.9 2002/12/29 21:30:12 scott Exp $ 14 | * 15 | * This file is distributed according to the GNU General Public 16 | * License. For full details, read the top of 'main.c' or the 17 | * file called COPYING that was distributed with this code. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include "sprintf.h" 26 | #include "timers.h" 27 | 28 | /* structure of a timer */ 29 | struct timer { 30 | char *id; 31 | time_t time; 32 | void (*function)(void *, void *); 33 | void *boundto; 34 | void *data; 35 | 36 | struct timer *next; 37 | }; 38 | 39 | /* forward declarations */ 40 | static int _timer_free(struct timer *); 41 | 42 | /* list of current timers */ 43 | static struct timer *timers = 0; 44 | 45 | /* next dynamic id */ 46 | static unsigned long nexttimer = 0; 47 | 48 | /* Check if a timer exists */ 49 | int timer_exists(void *b, const char *id) { 50 | struct timer *t; 51 | 52 | t = timers; 53 | while (t) { 54 | if ((b == t->boundto) && !strcmp(id, t->id)) 55 | return 1; 56 | t = t->next; 57 | } 58 | 59 | return 0; 60 | } 61 | 62 | /* Add a new timer */ 63 | char *timer_new(void *b, const char *id, unsigned long interval, 64 | void (*func)(void *, void *), void *data) { 65 | struct timer *t; 66 | 67 | if (id && timer_exists(b, id)) 68 | return 0; 69 | 70 | t = (struct timer *)malloc(sizeof(struct timer)); 71 | if (id) { 72 | t->id = x_strdup(id); 73 | } else { 74 | t->id = x_sprintf("timer%lu", nexttimer++); 75 | } 76 | t->time = (interval ? time(NULL) + interval : 0); 77 | t->function = func; 78 | t->boundto = b; 79 | t->data = data; 80 | 81 | t->next = timers; 82 | timers = t; 83 | 84 | debug("Timer %s will be triggered in %d seconds", t->id, 85 | (t->time ? t->time - time(NULL) : 0)); 86 | return t->id; 87 | } 88 | 89 | /* Delete a timer */ 90 | int timer_del(void *b, char *id) { 91 | struct timer *t, *l; 92 | 93 | l = 0; 94 | t = timers; 95 | 96 | while (t) { 97 | if ((b == t->boundto) && !strcmp(id, t->id)) { 98 | if (l) { 99 | l->next = t->next; 100 | } else { 101 | timers = t->next; 102 | } 103 | 104 | debug("Timer %s will not be triggered (%d on the clock)", 105 | t->id, (t->time ? t->time - time(NULL) : 0)); 106 | _timer_free(t); 107 | return 0; 108 | } else { 109 | l = t; 110 | t = t->next; 111 | } 112 | } 113 | 114 | return -1; 115 | } 116 | 117 | /* Delete all timers with a certain ircproxy class */ 118 | int timer_delall(void *b) { 119 | struct timer *t, *l; 120 | int numdone; 121 | 122 | l = 0; 123 | t = timers; 124 | numdone = 0; 125 | 126 | while (t) { 127 | if (t->boundto == b) { 128 | struct timer *n; 129 | 130 | n = t->next; 131 | debug("Timer %s will not be triggered (%d on the clock)", 132 | t->id, (t->time ? t->time - time(NULL) : 0)); 133 | _timer_free(t); 134 | 135 | if (l) { 136 | t = l->next = n; 137 | } else { 138 | t = timers = n; 139 | } 140 | 141 | numdone++; 142 | } else { 143 | l = t; 144 | t = t->next; 145 | } 146 | } 147 | 148 | return numdone; 149 | } 150 | 151 | /* Poll the timers */ 152 | int timer_poll(void) { 153 | struct timer *t, *l; 154 | time_t ctime; 155 | 156 | l = 0; 157 | t = timers; 158 | ctime = time(NULL); 159 | 160 | while (t) { 161 | 162 | if (t->time <= ctime) { 163 | void (*function)(void *, void *); 164 | struct timer *n; 165 | void *b, *data; 166 | 167 | function = t->function; 168 | b = t->boundto; 169 | data = t->data; 170 | n = t->next; 171 | debug("Timer %s triggered", t->id); 172 | _timer_free(t); 173 | 174 | if (l) { 175 | t = l->next = n; 176 | } else { 177 | t = timers = n; 178 | } 179 | 180 | if (function) 181 | function(b, data); 182 | } else { 183 | l = t; 184 | t = t->next; 185 | } 186 | } 187 | 188 | return (timers ? 1 : 0); 189 | } 190 | 191 | /* Free a timer */ 192 | static int _timer_free(struct timer *t) { 193 | free(t->id); 194 | free(t); 195 | return 0; 196 | } 197 | 198 | /* Get rid of all the proxies */ 199 | void timer_flush(void) { 200 | struct timer *t; 201 | 202 | t = timers; 203 | 204 | while (t) { 205 | struct timer *n; 206 | 207 | n = t->next; 208 | debug("Timer %s never triggered (%d on the clock)", 209 | t->id, (t->time ? t->time - time(NULL) : 0)); 210 | _timer_free(t); 211 | t = n; 212 | } 213 | 214 | timers = 0; 215 | } 216 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installing and Configuring dircproxy 2 | ------------------------------------ 3 | 4 | dircproxy is designed to run on any modern UNIX system, and should 5 | require little or no modification to work on yours. The only 6 | requisite it has is a modern libc with TCP/IP networking code. 7 | 8 | 9 | Compiling dircproxy 10 | =================== 11 | 12 | Installing dircproxy is fairly easy, and this overview will get it 13 | up and running for you in no time. 14 | 15 | You'll need to unpack the distribution file 'dircproxy-X.X.X.tar.gz' 16 | (where X.X.X is the version number you have downloaded) somewhere on 17 | your machine, if you don't know where to do it, your home directory 18 | is a good bet. (You've probably already done this to read this 19 | file anyway!) 20 | 21 | $ gunzip -c dircproxy-X.X.X.tar.gz | tar xf - 22 | 23 | This will place the source code for dircproxy in a directory called 24 | 'dircproxy-X.X.X'. To compile the program, you should be in this 25 | directory, so change to it now (again you've probably already 26 | done this). 27 | 28 | $ cd dircproxy-X.X.X 29 | 30 | You're now ready to begin. 31 | 32 | dircproxy uses the GNU standard 'configure' program to examine your 33 | system and find where required libraries and header files are. 34 | Most of the time this needs little or no interaction to get it 35 | to work. You should be able to get away with the following command: 36 | 37 | $ ./configure 38 | 39 | If it terminates with an error (it hopefully won't!) you should 40 | be able to use its output to discover what it needs, and fix the 41 | problem. By default, dircproxy is installed under the '/usr/local' 42 | hierarchy, if you wish to install it somewhere else you can pass 43 | the '--prefix' option to the 'configure' script. If you only wish 44 | to run it from your home directory, don't worry about this bit, 45 | it'll work for you with the default option. 46 | 47 | 'configure' accepts lots of other options, for more information 48 | run it with the --help option, or see "Configuring the Compilation" 49 | below. 50 | 51 | If you want to tinker with some of the more advanced configuration 52 | options of dircproxy, you can edit the src/dircproxy.h file at 53 | this point. This is not recommended unless you are an expert and 54 | wish to change something specific. 55 | 56 | You can now build the dircproxy binary, this is accomplished by 57 | the following command: 58 | 59 | $ make 60 | 61 | The dircproxy binary should now be in the src directory. If you 62 | only want to run it from your home directory, copy it somewhere 63 | sensible and skip down to "Configuring dircproxy" below. 64 | 65 | Otherwise, if you want to install dircproxy so it is available for 66 | anyone on the machine to use, then you will need to install it. 67 | You will most-likely need to switch to the 'root' user, either 68 | by using your system's 'su' command, or by logging in as 'root' 69 | onto another terminal. Once you are 'root', go to the dircproxy 70 | source directory (if necessary) and issue the following command: 71 | 72 | # make install 73 | 74 | The default binaries have debugging symbols left in them as this 75 | tends to be more useful than not. If you're tight on disk-space, 76 | you can install 'stripped' versions of the binaries without these 77 | debugging symbols by using the following command instead: 78 | 79 | # make install-strip 80 | 81 | 82 | Configuring dircproxy 83 | ===================== 84 | 85 | dircproxy requires a configuration file in order to run. This 86 | configuration file includes information on who can use the proxy 87 | and other options such as log file locations etc. 88 | 89 | An example file is in the 'conf' directory of the source code, and 90 | is called 'dircproxyrc'. If you installed using 'make install', 91 | then it will also be available for you and other users in the 92 | '/usr/local/share/dircproxy' directory. 93 | 94 | This file contains documentation on each of the configuration 95 | options. It is recommended that to create your configuration file, 96 | you copy the example and edit it, rather than simply writing your 97 | own from scratch. 98 | 99 | Exactly where you copy it depends on how you wish to run dircproxy. 100 | If you are going to be running it as a daemon on your system, for 101 | many people to use simultaneously, then '/usr/local/etc/dircproxyrc' 102 | is the recommended location. If you want to run it under your 103 | own user account, then '~/.dircproxyrc' is the best location. 104 | dircproxy automatically looks at these two locations for the config 105 | file, if you don't like either of them, then place the configuration 106 | file wherever you want and tell dircproxy using the '-f' command-line 107 | parameter, for example: 108 | 109 | $ dircproxy -f ./dircproxyrc 110 | 111 | 112 | Configuring the Compilation 113 | =========================== 114 | 115 | If have problems compiling dircproxy, or wish to customise the 116 | compilation, then you can pass various options to the 'configure' 117 | script to hopefully do you want you want. 118 | 119 | There are a large number of possible arguments, and only the more 120 | useful ones are documented here. 121 | 122 | '--help' 123 | Print a summary of all the options available. 124 | 125 | '--prefix=DIR' 126 | This is the root directory dircproxy is installed under 127 | when you do a 'make install'. The default is '/usr/local'. 128 | 129 | '--enable-debug' 130 | Enables the dircproxy debug mode, only useful if you want to 131 | help fix a bug you've found. Not recommended for normal use. 132 | 133 | '--enable-ssl' 134 | Enable SSL support (not working yet - on the 1.3.x roadmap) 135 | 136 | 137 | If compilation fails for any reason, you can pass shell variables 138 | to the 'configure' script to tell it about your system. A complete 139 | list of these variables can be found in the 'autoconf' documentation 140 | if you have it. You can do that on the command-line in a sh-like 141 | shell (such as bash) like this: 142 | 143 | $ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure 144 | 145 | Or on systems that have the 'env' program, you can do it like this: 146 | env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure 147 | 148 | 149 | 150 | Copyright (C) 2000-2003 Scott James Remnant 151 | 152 | Copyright (C) 2004-2008 Francois Harvey 153 | 154 | Copyright (C) 2008-2009 Noel Shrum 155 | Francois Harvey 156 | 157 | -------------------------------------------------------------------------------- /README.dcc-via-ssh: -------------------------------------------------------------------------------- 1 | Tunneling DCC over ssh using dircproxy 2 | --------------------------------------- 3 | 4 | WARNING, THIS IS NOT EASY TO DO. 5 | Don't read any further unless you are a fully qualified UNIX guru, 6 | complete with the long hair and sandals. 7 | 8 | 9 | Why do this? 10 | ============ 11 | 12 | DCC chats and sends will not work if your desktop is behind a 13 | firewall if that firewall prevents you from freely accessing the 14 | Internet, or prevents people from connecting to you. 15 | 16 | There are normal three ways around this. 17 | 18 | o Placing rules in the firewall that allow certain ports such as IRC 19 | through, and using the `dcc_proxy_ports` config option to limit 20 | dircproxy's port range to that which you've allowed. 21 | 22 | You probably don't have that kind of access to the firewall though, 23 | or wouldn't be allowed to if you did. 24 | 25 | o Install dircproxy on the firewall itself, so it can freely proxy 26 | between both networks without being affected by the rules on the 27 | firewall. 28 | 29 | Again, you probably don't have that kind of access. Its also not 30 | good practice anyway. 31 | 32 | o Piggy back your IRC traffic on something that the firewall does 33 | let through. 34 | 35 | Most firewalls let ssh traffic through, at least in the out-bound 36 | direction, and that's perfect. This is what this file tells you 37 | how to do. 38 | 39 | 40 | What do I need? 41 | =============== 42 | 43 | For this to work, the firewall must allow ssh traffic through 44 | and must allow connections to be made from inside the firewall 45 | to outside. It probably does, or you can probably persuade the 46 | firewall admin to let ssh through, its secure after all. 47 | 48 | 49 | You will also need two UNIX machines, one inside the firewall and 50 | one outside. 51 | 52 | The inside one must have dircproxy installed and ssh installed. 53 | The best choice is probably your desktop if that runs UNIX. 54 | (You *could* use a Windows machine if you can get dircproxy to 55 | compile on it and use something like SecureCRT of F-Secure SSH to 56 | do the tunnels). 57 | 58 | The outside machine must also have dircproxy installed, and must 59 | have the ssh daemon (sshd) installed and running. 60 | 61 | 62 | Setting up the Tunnels 63 | ====================== 64 | 65 | You'll need three different tunnels across the firewall from 66 | the machine inside to the machine outside. One to forward the 67 | IRC connection itself, and a further two for DCC traffic, one 68 | for incoming and one for outgoing. You can do this with one ssh 69 | command, specifying all three tunnels at the same time. (Replace 70 | 'outside.firewall' with the hostname of the machine outside). 71 | 72 | $ ssh -L 57010:localhost:57000 \ 73 | -L 57110:localhost:57100 \ 74 | -R 57110:localhost:57100 outside.firewall 75 | 76 | This will actually start a shell on the remote machine. Exiting from 77 | it will end the tunnels. For safety you may want to run this under 78 | screen or something (if you've got that), as it doesn't run in the 79 | background either. Its perfectly safe to close the tunnels while you 80 | are detatched though - so you could put these in a shell script or 81 | something instead and just run that when you want to attach. 82 | 83 | 84 | Configuring dircproxy on the Outside machine 85 | ============================================ 86 | 87 | This will be the master dircproxy, connecting to the IRC server 88 | itself and doing all the normal things such as logging etc. 89 | Configure it as you normally would, except for the following two 90 | options which need to be set as shown. 91 | 92 | dcc_proxy_ports 57100 93 | dcc_tunnel_outgoing 57110 94 | 95 | This tells dircproxy to listen for DCC connections on port 57100, 96 | which is pointed to by a tunnel, and that all outgoing DCCs from you 97 | (which require a connection to you) should be sent through the tunnel 98 | on port 57110. 99 | 100 | This dircproxy is probably best run as a daemon (i.e. normally). 101 | 102 | 103 | Configuring dircproxy on the Inside machine 104 | =========================================== 105 | 106 | This dircproxy will be a simple slave, forwarding to the one outside 107 | without doing anything clever. The configuration file should be left 108 | untouched, only add a connection class, which should look like this. 109 | 110 | connection { 111 | password "encpass" 112 | server "localhost:57010:pass" 113 | 114 | disconnect_on_detach yes 115 | 116 | dcc_proxy_ports 57100 117 | dcc_tunnel_incoming 57110 118 | } 119 | 120 | Replace "encpass" with an encrypted password that should match 121 | that you configure the IRC client with, and replace "pass" with 122 | the unencrypted version of whatever you set the password to on the 123 | dircproxy outside the firewall. 124 | 125 | This tells dircproxy that incoming DCC requests to you (which require 126 | you to connect to the remote server) should be sent through the tunnel 127 | on port 57110. 128 | 129 | You can run this dircproxy as a daemon or from inetd, whichever 130 | suits you best. 131 | 132 | 133 | Using dircproxy now 134 | =================== 135 | 136 | Connect your IRC client to the dircproxy inside the firewall. 137 | This will then connect through the tunnels to the dircproxy outside 138 | the firewall which will connect to the IRC server for you. 139 | 140 | When you detach your IRC client, the dircproxy inside the firewall 141 | will disconnect from the one on the outside. This means you can 142 | also exit the ssh session running the tunnels (thereby closing them). 143 | When you want to reconnect, just start up the tunnels and dircproxy 144 | again before you do (having left the one outside well alone). This 145 | means that if you are using your desktop, you can still switch it off 146 | over night etc without worrying about loosing your IRC link. 147 | 148 | Small note: Because you can only use one listening port, you will only 149 | be able to have one queued DCC request at a time. Others will be 150 | rejected until the outstanding request either times out or is 151 | accepted by you. 152 | 153 | Another worthy note is that when using tunnels, you will see two sets 154 | of messages from dircproxy informing you of its connections to remote 155 | peers. The first set is the link between the two proxies being 156 | established, the second set is the link being established to the 157 | remote peer itself. This is normal and nothing to worry about. 158 | 159 | 160 | Copyright (C) 2000-2003 Scott James Remnant 161 | 162 | Copyright (C) 2004-2008 Francois Harvey 163 | 164 | Copyright (C) 2008-2009 Noel Shrum 165 | Francois Harvey 166 | 167 | -------------------------------------------------------------------------------- /crypt/main.c: -------------------------------------------------------------------------------- 1 | /* dircproxy-crypt 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * main.c 11 | * - Encrypt a password taken from stdin or the command line 12 | * 13 | * -- 14 | * @(#) $Id: main.c,v 1.4 2002/12/29 21:30:10 scott Exp $ 15 | * 16 | * This program is free software; you can redistribute it and/or modify 17 | * it under the terms of the GNU General Public License as published by 18 | * the Free Software Foundation; either version 2 of the License, or 19 | * (at your option) any later version. 20 | * 21 | * This program is distributed in the hope that it will be useful, 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | * GNU General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU General Public License 27 | * along with this program; if not, write to the Free Software 28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifdef HAVE_CONFIG_H 37 | #include 38 | #else /* HAVE_CONFIG_H */ 39 | #define PACKAGE "dircproxy" 40 | #define VERSION "-debug" 41 | #endif /* HAVE_CONFIG_H */ 42 | 43 | #ifdef HAVE_CRYPT_H 44 | #include 45 | #else /* HAVE_CRYPT_H */ 46 | #include 47 | #endif /* HAVE_CRYPT_H */ 48 | 49 | #include "getopt/getopt.h" 50 | 51 | /* forward declarations */ 52 | static void _encrypt(const char *); 53 | static void _encrypt_md5(const char *); 54 | static void _saltchar(char *); 55 | static int _print_usage(void); 56 | static int _print_version(void); 57 | static int _print_help(void); 58 | 59 | /* This is so "ident" and "what" can query version etc - userful (not) */ 60 | const char *rcsid = "@(#) $Id: main.c,v 1.4 2002/12/29 21:30:10 scott Exp $"; 61 | 62 | /* The name of the program */ 63 | static char *progname; 64 | 65 | /* Long options */ 66 | static struct option long_opts[] = { 67 | { "help", 0, NULL, 'h' }, 68 | { "md5", 0, NULL, 'm' }, 69 | { "version", 0, NULL, 'v' }, 70 | { 0, 0, 0, 0} 71 | }; 72 | 73 | /* Options */ 74 | #define GETOPTIONS "hmv" 75 | 76 | /* The main func */ 77 | int main(int argc, char *argv[]) { 78 | int optc, show_help, show_version, show_usage, use_md5; 79 | 80 | /* Get arguments */ 81 | progname = argv[0]; 82 | show_help = show_version = show_usage = use_md5 = 0; 83 | while ((optc = getopt_long(argc, argv, GETOPTIONS, long_opts, NULL)) != -1) { 84 | switch (optc) { 85 | case 'h': 86 | show_help = 1; 87 | break; 88 | case 'm': 89 | use_md5 = 1; 90 | break; 91 | case 'v': 92 | show_version = 1; 93 | break; 94 | default: 95 | show_usage = 1; 96 | break; 97 | } 98 | } 99 | 100 | if (show_usage) { 101 | _print_usage(); 102 | return 1; 103 | } 104 | 105 | if (show_version) { 106 | _print_version(); 107 | if (!show_help) 108 | return 0; 109 | } 110 | 111 | if (show_help) { 112 | _print_help(); 113 | return 0; 114 | } 115 | 116 | /* Randomize */ 117 | srand(time(0)); 118 | 119 | if (optind < argc) { 120 | while (optind < argc) { 121 | if (use_md5) 122 | _encrypt_md5(argv[optind]); 123 | else 124 | _encrypt(argv[optind]); 125 | optind++; 126 | } 127 | } else { 128 | char pass[80], *ret; 129 | 130 | printf("Password: "); 131 | ret = fgets(pass, sizeof(pass), stdin); 132 | printf("\n"); 133 | if (ret) { 134 | char *ptr; 135 | 136 | ptr = pass + strlen(pass); 137 | while ((ptr >= ret) && (*ptr <= 32)) *(ptr--) = 0; 138 | if (use_md5) 139 | _encrypt_md5(pass); 140 | else 141 | _encrypt(pass); 142 | } 143 | } 144 | 145 | return 0; 146 | } 147 | 148 | /* Encrypt a password */ 149 | static void _encrypt(const char *pass) { 150 | char salt[3], *enc; 151 | 152 | _saltchar(&(salt[0])); 153 | _saltchar(&(salt[1])); 154 | salt[2] = 0; 155 | 156 | enc = crypt(pass, salt); 157 | printf("(DES) %s = %s\n", pass, enc); 158 | } 159 | 160 | /* Encrypt a password */ 161 | static void _encrypt_md5(const char *pass) 162 | { 163 | 164 | char salt[13], *enc; 165 | salt[0] = '$'; 166 | salt[1] = '1'; 167 | salt[2] = '$'; 168 | _saltchar(&(salt[3])); 169 | _saltchar(&(salt[4])); 170 | _saltchar(&(salt[5])); 171 | _saltchar(&(salt[6])); 172 | _saltchar(&(salt[7])); 173 | _saltchar(&(salt[8])); 174 | _saltchar(&(salt[9])); 175 | _saltchar(&(salt[10])); 176 | salt[11] = '$'; 177 | salt[12] = 0; 178 | 179 | enc = crypt(pass, salt); 180 | printf("(MD5) %s = %s\n", pass, enc); 181 | } 182 | 183 | 184 | 185 | /* Pick a random salt character */ 186 | static void _saltchar(char *c) { 187 | static char *chars = "abcdefghijklmnopqrstuvwxyz" 188 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 189 | "01234567890"; 190 | int ran; 191 | 192 | ran = (int)((double)(strlen(chars) - 1) * (rand() / (RAND_MAX + 1.0))); 193 | *c = chars[ran]; 194 | } 195 | 196 | /* Print the usage instructions to stderr */ 197 | static int _print_usage(void) { 198 | fprintf(stderr, "%s: Try '%s --help' for more information.\n", 199 | progname, progname); 200 | 201 | return 0; 202 | } 203 | 204 | /* Print the version number to stderr */ 205 | static int _print_version(void) { 206 | fprintf(stderr, "dircproxy-crypt (%s %s)\n", PACKAGE, VERSION); 207 | 208 | return 0; 209 | } 210 | 211 | /* Print the help to stderr */ 212 | static int _print_help(void) { 213 | fprintf(stderr, "dircproxy-crypt. Encyrpt passwords for %s.\n\n", PACKAGE); 214 | fprintf(stderr, "Usage: %s [OPTION]... [PASSWORD]...\n\n", progname); 215 | fprintf(stderr, "If a long option shows an argument as mandatory, then " 216 | "it is mandatory\nfor the equivalent short option also. " 217 | "Similarly for optional arguments.\n\n"); 218 | fprintf(stderr, " -h, --help Print a summary of the options\n"); 219 | fprintf(stderr, " -m, --md5 Generate a md5 password\n"); 220 | fprintf(stderr, " -v, --version Print the version number\n\n"); 221 | fprintf(stderr, " PASSWORD Plaintext password to crypt\n\n"); 222 | fprintf(stderr, "If no passwords are given on the command line, you will " 223 | "be asked for one\non standard input.\n\n"); 224 | 225 | return 0; 226 | } 227 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | dircproxy: Detachable IRC Proxy Server 2 | ------------------------------------- 3 | 4 | ---------------------------------------------- 5 | WARNING : 1.2.0-RC1 is currently unstable 6 | ---------------------------------------------- 7 | 8 | dircproxy is an IRC proxy server ("bouncer") designed for people 9 | who use IRC from lots of different workstations or clients, but wish 10 | to remain connected and see what they missed while they were away. 11 | You connect to IRC through dircproxy, and it keeps you connected to 12 | the server, even after you detach your client from it. While you're 13 | detached, it logs channel and private messages as well as important 14 | events, and when you re-attach it'll let you know what you missed. 15 | 16 | This can be used to give you roughly the same functionality as 17 | using ircII and screen together, except you can use whatever IRC 18 | client you like, including X ones! 19 | 20 | 21 | Features 22 | ======== 23 | 24 | o Runs on console, as a daemon or from inetd. 25 | o Able to proxy many simultaneous users and IRC connections. 26 | o Uses IRC server passwords to authenticate. 27 | o Remains connected to server when you detach. To reattach you just 28 | use the IRC server password again, no special commands! 29 | o Completely non-blocking throughout. 30 | o Can connect to servers that also require a password. 31 | o Can have a list of servers on the same network to connect to, it 32 | will cycle this list. 33 | o Throttles data sent to server to ensure you are never flooded 34 | off. 35 | o Can check servers to make sure they don't become "stoned". 36 | o Reconnects to servers if connection is dropped. 37 | o Can automatically join channels for you on first attach. 38 | o Rejoins channels if you are kicked off. 39 | o Can leave channels when you detach and rejoin when you come back. 40 | o Can take measures to ensure you don't appear "idle" on IRC. 41 | o Drop's unwanted user modes when you detached, if you forget to 42 | de-opper yourself. 43 | o Will refuse to connect to servers that set certain modes 44 | such as +r. 45 | o Can bind to any IP on your host to change your appearance on IRC. 46 | o Can change what username is presented on IRC without affecting 47 | other users its proxying for. 48 | o Can send a message to all channels to indicate when you detach 49 | and reattach. 50 | o Can change your nickname when you detach. 51 | o Sets you /AWAY when you detach, if you forget to do so. 52 | o Fully configurable logging support so when you reattach you 53 | can see what you missed. 54 | o Can limit the size of log files to avoid eating diskspace. 55 | o Log text recalled to your client is sent so your client sees 56 | it as ordinary IRC text. 57 | o Can timestamp text in log files so you know when it was sent, 58 | also can adjust the timestamp you see depending on how long ago 59 | it was sent. 60 | o Can make permanent log files for your own use of everything 61 | on channels or all private messages. 62 | o Can pass log text to a program of your choice (to send you 63 | an SMS for example). 64 | o Can adjust log timestamps depending on timezone difference 65 | between you and dircproxy. 66 | o Can proxy DCC chat and sends through itself. 67 | o Can capture DCC sends and store them on the dircproxy machine 68 | while you're detached, and even while you're attached. 69 | o Captured DCC sends can be made subject to a size limit and have 70 | the sender's nickname included in the filename. 71 | o Can tunnel DCC sends and chats through ssh tunnels. 72 | See the included README.dcc-via-ssh for more information. 73 | o Customisable message of the day for users which can include 74 | stats about log file sizes. 75 | o /DIRCPROXY command interface for users to do extra things with 76 | the proxy. Fully documented through /DIRCPROXY HELP command, and 77 | the admin can enable and disable any command on 78 | a user-by-user basis. 79 | o Host and password based security. 80 | o Easy to configure and get running. 81 | 82 | All of dircproxy's features are completely configurable and can be 83 | enabled, disabled and adjusted through the configuration file. 84 | 85 | 86 | Installation 87 | ============ 88 | 89 | See the file INSTALL for building and installation instructions. 90 | 91 | 92 | Running dircproxy 93 | ================= 94 | 95 | 96 | Once you have installed and configured dircproxy, you can run it 97 | from the console. It will automatically enter the background 98 | (unless you supply the '-D' parameter) and begin listening for 99 | incoming connections. 100 | 101 | You should not need to modify your IRC client or add any 102 | special scripts to support dircproxy. Authentication is done 103 | using the standard IRC server password, your IRC client should 104 | support this. If you're not sure, try something like '/server 105 | localhost:57000:password' from your IRC client's console. 106 | 107 | Connect to it with your IRC client, supplying the same password as 108 | you set in the config file, dircproxy will then connect to the IRC 109 | server for you and begin proxying your session. 110 | 111 | When you detach, dircproxy will remain running and remain connected 112 | to the IRC server, logging any channel or private messages for you 113 | until your return. 114 | 115 | To re-attach, just connect with your IRC client, again supplying 116 | the password. dircproxy will see you have left a session running and 117 | re-attach you to that instead of creating a new one. Messages you 118 | missed while you were away will be sent to you in such a way that 119 | they will fill your IRC windows as if they'd just arrived. 120 | 121 | 122 | You can also run dircproxy from inetd if you wish, although their 123 | are very few reasons to do this. See the file README.inetd for 124 | more information on this feature. 125 | 126 | 127 | Adjusting the Proxy 128 | =================== 129 | 130 | While you are connected to the proxy you may perform a number of 131 | actions to adjust your proxy session using the '/dircproxy' command. 132 | For example, to end your proxy session, disconnecting you from the 133 | server, use '/dircproxy quit'. For more information on what other 134 | commands are available, see '/dircproxy help'. 135 | 136 | 137 | More Information 138 | ================ 139 | 140 | The dircproxy home page is at: 141 | 142 | http://code.google.com/p/dircproxy/ 143 | 144 | 145 | Please submit bug reports at: 146 | 147 | http://code.google.com/p/dircproxy/issues/entry 148 | 149 | Also join us on the #dircproxy IRC channel on irc.freenode.org 150 | 151 | 152 | dircproxy is distributed according to the GNU General Public License. 153 | See the file COPYING for details. 154 | 155 | 156 | Copyright (C) 2000-2003 Scott James Remnant 157 | 158 | Copyright (C) 2004-2008 Francois Harvey 159 | 160 | Copyright (C) 2008-2009 Noel Shrum 161 | Francois Harvey 162 | 163 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | NEWS about changes for existing users. 2 | -------------------------------------- 3 | 4 | Version 1.2.0-RC1 - 09 jan 2009 5 | * Lot of bugfixes 6 | 7 | Version 1.2.0-beta - 25 Oct 2005 8 | * Nickserv support 9 | * Binding to a local IP 10 | * a new /dircproxy RELOAD to reload the config 11 | * Add DCC Resume 12 | * Add 005 Support 13 | * Support for IPV6 (experimental) 14 | * a new /dircproxy NOTIFY command 15 | * Support for MD5 password 16 | 17 | Version 1.1.0 - Sun Aug 18 02:45:00 BST 2002 18 | 19 | * New 'log_timestamp' config directive. 20 | * Removed 'chan_log_timestamp' and 'other_log_timestamp' 21 | config directives. 22 | * New 'log_relativetime' config directive. 23 | * Removed 'chan_log_relativetime' and 'other_log_relativetime' 24 | config directives. 25 | * New 'log_dir' config directive. 26 | * Removed 'chan_log_copydir' and 'other_log_copydir' config directives. 27 | * New 'log_program' config directive. 28 | * Removed 'chan_log_program' and 'other_log_program' config directives. 29 | * New 'server_log_enabled', 'server_log_always', 'server_log_maxlines' 30 | and 'server_log_recall' config directives. 31 | * Removed 'other_log_enabled', 'other_log_always', 'other_log_maxlines' 32 | and 'other_log_recall' config directives. 33 | * Private messages seperated from server messages, new directives 34 | 'private_log_enabled', 'private_log_always', 'private_log_maxlines' 35 | and 'private_log_recall' 36 | * Log file format created by 'log_dir' no longer has '@1234' on the 37 | front if 'log_relativetime' is 'yes' 38 | 39 | Version 1.0.3 - Fri Feb 8 17:45:00 GMT 2002 40 | 41 | * New 'pid_file', 'allow_users' and 'allow_kill' config 42 | directives. 43 | * New -p command line parameter (adjusts pid_file). 44 | * Included contrib scripts, cronchk.sh and privmsg-log.pl 45 | 46 | Version 1.0.2 - Tue Jan 1 18:15:00 GMT 2001 47 | 48 | * New 'server_keepalive' config directive. 49 | 50 | Version 1.0.1 - Wed Jul 12 17:00:00 BST 2001 51 | 52 | * Just bug fixes. No changes to worry about. 53 | 54 | Version 1.0.0 - Thu Jan 11 15:20:00 GMT 2001 55 | 56 | * Just bug fixes. No changes to worry about. 57 | 58 | Version 0.99.0 - Tue Dec 26 17:55:00 GMT 2000 59 | 60 | * New 'nick_keep' config directive. The nickname code has been 61 | reworked to accomodate this, as such if the connecting client 62 | has a different nickname to dircproxy, the connecting client is 63 | now corrected (not dircproxy, as it used to be). 64 | 65 | * New 'ctcp_replies' config directive. 66 | 67 | Version 0.8.4 - Thu Dec 7 17:35:00 GMT 2000 68 | 69 | * New 'initial_modes' config directive. 70 | 71 | Version 0.8.3 - Thu Nov 24 13:45:00 GMT 2000 72 | 73 | * Just bug fixes. No changes to worry about. 74 | 75 | Version 0.8.2 - Thu Nov 23 12:30:00 GMT 2000 76 | 77 | * Just bug fixes. No changes to worry about. 78 | 79 | Version 0.8.1 - Wed Nov 15 16:25:00 GMT 2000 80 | 81 | * Just bug fixes. No changes to worry about. 82 | 83 | Version 0.8.0 - Fri Nov 10 15:20:00 GMT 2000 84 | 85 | * 'chan_log_dir' and 'other_log_dir' have been removed because 86 | they cause usage and security problems. These have been replaced 87 | with 'chan_log_copydir' and 'other_log_copydir' which have a 88 | slightly different purpose. 89 | 90 | * The log file format on disk has changed slightly to allow for the 91 | new 'relative timestamping'. 92 | 93 | * DCC chat's and send's are now proxied by default through dircproxy. 94 | 95 | * Removed config file options: 96 | server_dnsretry 97 | 98 | * New config file options: 99 | client_timeout 100 | connect_timeout 101 | dns_timeout 102 | server_throttle 103 | server_autoconnect 104 | channel_leave_on_detach 105 | channel_rejoin_on_attach 106 | idle_maxtime 107 | refuse_modes 108 | quit_message 109 | attach_message 110 | detach_message 111 | chan_log_enabled 112 | chan_log_relativetime 113 | chan_log_program 114 | other_log_enabled 115 | other_log_relativetime 116 | other_log_program 117 | log_timeoffset 118 | log_events 119 | dcc_proxy_incoming 120 | dcc_proxy_outgoing 121 | dcc_proxy_ports 122 | dcc_proxy_timeout 123 | dcc_proxy_sendreject 124 | dcc_send_fast 125 | dcc_capture_directory 126 | dcc_capture_always 127 | dcc_capture_withnick 128 | dcc_capture_maxsize 129 | dcc_tunnel_incoming 130 | dcc_tunnel_outgoing 131 | switch_user 132 | motd_file 133 | allow_persist 134 | allow_jump 135 | allow_jump_new 136 | allow_host 137 | allow_die 138 | 139 | Version 0.7.3 - Wed Sep 27 17:55:00 BST 2000 140 | 141 | * New config file option - "disconnect_on_detach" 142 | 143 | Version 0.7.2 - Mon Sep 25 13:13:00 BST 2000 144 | 145 | * If you use a .dircproxyrc in your home directory, this must 146 | now have no more then 0700 permissions. If this is not the 147 | case then dircproxy will not start. This does not apply to 148 | the global config file or any supplied with the -f parameter. 149 | 150 | Version 0.7.1 - Thu Sep 14 13:15:00 BST 2000 151 | 152 | * Just bug fixes. No changes to worry about. 153 | 154 | Version 0.7.0 - Fri Sep 1 15:00:00 BST 2000 155 | 156 | * The global configuration file is now called dircproxyrc not 157 | dircproxy.conf 158 | 159 | * dircproxy is now installed in 'bin' not 'sbin', its a user 160 | program after all. 161 | 162 | * Passwords for connection classes must be encrypted in the 163 | configuration file using the crypt() function (or contrib/crypt), 164 | if you don't like this then edit src/dircproxy.h and turn it off, 165 | but thats silly. 166 | 167 | * /DQUIT is gone, try /DIRCPROXY QUIT instead 168 | 169 | * Try /DIRCPROXY HELP 170 | 171 | * Try "man dircproxy" :-) 172 | 173 | Version 0.6.2 - Mon Jun 26 16:58:00 BST 2000 174 | 175 | * Changed the logic behind how configuration files are loaded. 176 | If you supply one with -f, that is loaded. If you don't it 177 | first tries ~/.dircproxyrc and then tries etc/dircproxy.conf. 178 | This means that the config file is no longer installed, and 179 | can be found as dircproxy.conf in share/dircproxy or the conf 180 | dir of the source. Also the -G option is no longer valid. 181 | 182 | Version 0.6.1 - Thu May 25 15:04:00 BST 2000 183 | 184 | * Just bug fixes. No changes to worry about. 185 | 186 | Version 0.6.0 - Wed May 24 22:33:00 BST 2000 187 | 188 | * There is now a configuration file. Copy the dircproxyrc.example 189 | from the conf directory to your home directory and call it 190 | .dircproxyrc - this file contains all the documentation for 191 | configuring dircproxy. 192 | 193 | Version 0.5.3 - Sat May 13 16:32:00 BST 2000 194 | 195 | * Many of the TODO_CFG_* options defined in dircproxy.h have now 196 | been given documentation and renamed. You'll need to recheck this 197 | file if you've changed them. The PASS/SERVER/BIND ones are still 198 | at the bottom and still the same however. 199 | 200 | Version 0.5.2 - Fri May 12 23:00:00 BST 2000 201 | 202 | * Initial public release 203 | 204 | 205 | Copyright (C) 2000-2003 Scott James Remnant 206 | 207 | Copyright (C) 2004-2008 Francois Harvey 208 | 209 | Copyright (C) 2008-2009 Noel Shrum 210 | Francois Harvey 211 | 212 | -------------------------------------------------------------------------------- /src/dcc_send.c: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000,2001,2002,2003 Scott James Remnant . 3 | * 4 | * dcc_send.c 5 | * - DCC send protocol 6 | * -- 7 | * @(#) $Id: dcc_send.c,v 1.15 2002/12/29 21:30:11 scott Exp $ 8 | * 9 | * This file is distributed according to the GNU General Public 10 | * License. For full details, read the top of 'main.c' or the 11 | * file called COPYING that was distributed with this code. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include "sprintf.h" 26 | #include "net.h" 27 | #include "dns.h" 28 | #include "timers.h" 29 | #include "dcc_net.h" 30 | #include "dcc_send.h" 31 | 32 | /* forward declarations */ 33 | static void _dccsend_data(struct dccproxy *, int); 34 | static void _dccsend_error(struct dccproxy *, int, int); 35 | static int _dccsend_sendpacket(struct dccproxy *); 36 | 37 | /* Called when we've connected to the sender */ 38 | void dccsend_connected(struct dccproxy *p, int sock) { 39 | if (sock != p->sender_sock) { 40 | error("Unexpected socket %d in dccsend_connected, expected %d", sock, 41 | p->sender_sock); 42 | net_close(&sock); 43 | return; 44 | } 45 | 46 | debug("DCC Connection succeeded"); 47 | p->sender_status |= DCC_SENDER_CONNECTED; 48 | net_hook(p->sender_sock, SOCK_NORMAL, (void *)p, 49 | ACTIVITY_FUNCTION(_dccsend_data), 50 | ERROR_FUNCTION(_dccsend_error)); 51 | } 52 | 53 | /* Called when a connection fails */ 54 | void dccsend_connectfailed(struct dccproxy *p, int sock, int bad) { 55 | if (sock != p->sender_sock) { 56 | error("Unexpected socket %d in dccsend_connectfailed, expected %d", sock, 57 | p->sender_sock); 58 | net_close(&sock); 59 | return; 60 | } 61 | 62 | if (p->notify_func) 63 | p->notify_func(p->notify_data, p->notify_msg, 64 | "Connection to remote peer failed"); 65 | 66 | debug("DCC Connection failed"); 67 | p->sender_status &= ~(DCC_SENDER_CREATED); 68 | net_close(&(p->sender_sock)); 69 | p->dead = 1; 70 | } 71 | 72 | /* Called when the sendee has been accepted */ 73 | void dccsend_accepted(struct dccproxy *p) { 74 | net_hook(p->sendee_sock, SOCK_NORMAL, (void *)p, 75 | ACTIVITY_FUNCTION(_dccsend_data), 76 | ERROR_FUNCTION(_dccsend_error)); 77 | 78 | /* If we've already got data, we better some */ 79 | if (p->bufsz) 80 | _dccsend_sendpacket(p); 81 | } 82 | 83 | /* Called when we get data over a DCC link */ 84 | static void _dccsend_data(struct dccproxy *p, int sock) { 85 | if (sock == p->sender_sock) { 86 | int buflen, nr; 87 | 88 | /* Read the data into the buffer */ 89 | buflen = net_read(p->sender_sock, 0, 0); 90 | p->buf = (char *)realloc(p->buf, p->bufsz + buflen); 91 | nr = net_read(p->sender_sock, (void *)(p->buf + p->bufsz), buflen); 92 | 93 | /* Check we read some */ 94 | if (nr > 0) { 95 | uint32_t na; 96 | int ret; 97 | 98 | p->bufsz += nr; 99 | p->bytes_rcvd += nr; 100 | 101 | /* Acknowledge them */ 102 | na = htonl(p->bytes_rcvd); 103 | ret = net_queue(p->sender_sock, (void *)&na, sizeof(uint32_t)); 104 | if (ret) { 105 | error("Couldn't queue data in dccsend_data"); 106 | net_close(&sock); 107 | return; 108 | } 109 | } else { 110 | p->buf = (char *)realloc(p->buf, p->bufsz); 111 | } 112 | 113 | } else if (sock == p->sendee_sock) { 114 | uint32_t ack; 115 | int len; 116 | 117 | /* We should only ever get ack's back */ 118 | len = net_read(p->sendee_sock, (void *)&ack, sizeof(uint32_t)); 119 | if (len == sizeof(uint32_t)) 120 | p->bytes_ackd = ntohl(ack); 121 | 122 | } else { 123 | error("Unexpected socket %d in dccsend_data, expected %d or %d", sock, 124 | p->sender_sock, p->sendee_sock); 125 | net_close(&sock); 126 | return; 127 | } 128 | 129 | /* Receiving data is as good as trigger as any to check whether we can send 130 | more. */ 131 | if (p->bufsz && ((p->type & DCC_SEND_FAST) || (p->type & DCC_SEND_CAPTURE) || 132 | (p->bytes_ackd >= p->bytes_sent))) { 133 | /* Capturing? Just eat the buffer right here, right now */ 134 | if (p->type & DCC_SEND_CAPTURE) { 135 | /* Write it to the file */ 136 | fwrite((void *)p->buf, 1, p->bufsz, p->cap_file); 137 | 138 | /* Sent the whole thing */ 139 | p->bytes_sent += p->bufsz; 140 | p->bufsz = 0; 141 | free(p->buf); 142 | p->buf = 0; 143 | 144 | /* Check we haven't exceeded the maximum size */ 145 | if (p->bytes_max && (p->bytes_sent >= p->bytes_max)) { 146 | /* We have, kill it. It'll automatically get unlinked */ 147 | debug("Too big for my boots!"); 148 | p->dead = 1; 149 | } 150 | 151 | } else if (p->sendee_status == DCC_SENDEE_ACTIVE) { 152 | /* Send packet to the client */ 153 | _dccsend_sendpacket(p); 154 | } 155 | } 156 | } 157 | 158 | /* Called on DCC disconnection or error */ 159 | static void _dccsend_error(struct dccproxy *p, int sock, int bad) { 160 | char *who; 161 | 162 | if (sock == p->sender_sock) { 163 | who = "Sender"; 164 | p->sender_status &= ~(DCC_SENDER_CREATED); 165 | net_close(&(p->sender_sock)); 166 | 167 | /* Not necessarily bad, just means the client has gone */ 168 | if (p->bufsz && !(p->type & DCC_SEND_CAPTURE)) { 169 | p->sender_status = DCC_SENDER_GONE; 170 | } else { 171 | p->dead = 1; 172 | } 173 | } else if (sock == p->sendee_sock) { 174 | who = "Sendee"; 175 | p->sendee_status &= ~(DCC_SENDEE_CREATED); 176 | net_close(&(p->sendee_sock)); 177 | p->dead = 1; 178 | } else { 179 | error("Unexpected socket %d in dccsend_error, expected %d or %d", sock, 180 | p->sender_sock, p->sendee_sock); 181 | net_close(&sock); 182 | return; 183 | } 184 | 185 | if (bad) { 186 | debug("Socket error with %s", who); 187 | } else { 188 | debug("%s disconnected", who); 189 | 190 | /* Close the file nicely if we're capturing, so it doesn't get unlinked */ 191 | if (p->type & DCC_SEND_CAPTURE) { 192 | debug("%s closed", p->cap_filename); 193 | free(p->cap_filename); 194 | fclose(p->cap_file); 195 | p->cap_filename = 0; 196 | p->cap_file = 0; 197 | } 198 | } 199 | } 200 | 201 | /* Send a packet of buffered data to the client */ 202 | static int _dccsend_sendpacket(struct dccproxy *p) { 203 | unsigned long nr; 204 | 205 | /* If we're doing simple sends, we limit the amount we send, if doing fast 206 | just shove the whole lot to them */ 207 | if (p->type & DCC_SEND_FAST) { 208 | nr = p->bufsz; 209 | } else { 210 | nr = (p->bufsz > DCC_BLOCK_SIZE ? DCC_BLOCK_SIZE : p->bufsz); 211 | } 212 | 213 | /* Send it to the sendee */ 214 | if (nr) { 215 | int ret; 216 | 217 | ret = net_queue(p->sendee_sock, (void *)p->buf, nr); 218 | if (ret) { 219 | error("Couldn't queue data in dccsend_data"); 220 | net_close(&(p->sendee_sock)); 221 | return -1; 222 | } 223 | 224 | /* Adjust or free the buffer */ 225 | p->bytes_sent += nr; 226 | p->bufsz -= nr; 227 | if (p->bufsz) { 228 | memmove(p->buf, p->buf + nr, p->bufsz); 229 | p->buf = (char *)realloc(p->buf, p->bufsz); 230 | } else { 231 | free(p->buf); 232 | p->buf = 0; 233 | } 234 | } 235 | 236 | /* Out of buffer and the sender has gone */ 237 | if (!p->bufsz && (p->sender_status == DCC_SENDER_GONE)) 238 | p->dead = 1; 239 | 240 | return nr; 241 | } 242 | -------------------------------------------------------------------------------- /src/irc_net.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * irc_net.h 10 | * -- 11 | * @(#) $Id: irc_net.h,v 1.55 2004/02/26 20:06:15 fharvey Exp $ 12 | * 13 | * This file is distributed according to the GNU General Public 14 | * License. For full details, read the top of 'main.c' or the 15 | * file called COPYING that was distributed with this code. 16 | */ 17 | 18 | #ifndef __DIRCPROXY_IRC_NET_H 19 | #define __DIRCPROXY_IRC_NET_H 20 | 21 | /* required includes */ 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "irc_prot.h" 31 | #include "stringex.h" 32 | #include "net.h" 33 | 34 | /* a log file - there are good reasons why this isn't defined in irc_log.h */ 35 | typedef struct logfile { 36 | int open, made; 37 | char *filename; 38 | FILE *file; 39 | 40 | unsigned long nlines, maxlines; 41 | 42 | int always; 43 | } LogFile; 44 | 45 | /* a description of an authorised connction */ 46 | typedef struct ircconnclass { 47 | char *server_port; 48 | long server_retry; 49 | long server_dnsretry; 50 | long server_maxattempts; 51 | long server_maxinitattempts; 52 | int server_keepalive; 53 | long server_pingtimeout; 54 | long *server_throttle; 55 | int server_autoconnect; 56 | 57 | long channel_rejoin; 58 | int channel_leave_on_detach; 59 | int channel_rejoin_on_attach; 60 | 61 | long idle_maxtime; 62 | 63 | int disconnect_existing; 64 | int disconnect_on_detach; 65 | 66 | char *initial_modes; 67 | char *drop_modes; 68 | char *refuse_modes; 69 | 70 | char *local_address; 71 | 72 | char *away_message; 73 | char *quit_message; 74 | char *attach_message; 75 | char *detach_message; 76 | char *detach_nickname; 77 | 78 | int nick_keep; 79 | 80 | char *nickserv_password; 81 | 82 | int ctcp_replies; 83 | 84 | long log_timeoffset; 85 | int log_events; 86 | int log_timestamp; 87 | int log_relativetime; 88 | char *log_dir; 89 | char *log_program; 90 | 91 | int chan_log_enabled; 92 | int chan_log_always; 93 | long chan_log_maxsize; 94 | long chan_log_recall; 95 | 96 | int private_log_enabled; 97 | int private_log_always; 98 | long private_log_maxsize; 99 | long private_log_recall; 100 | 101 | int server_log_enabled; 102 | int server_log_always; 103 | long server_log_maxsize; 104 | long server_log_recall; 105 | 106 | int dcc_proxy_incoming; 107 | int dcc_proxy_outgoing; 108 | int *dcc_proxy_ports; 109 | size_t dcc_proxy_ports_sz; 110 | long dcc_proxy_timeout; 111 | int dcc_proxy_sendreject; 112 | 113 | int dcc_send_fast; 114 | 115 | char *dcc_capture_directory; 116 | int dcc_capture_always; 117 | int dcc_capture_withnick; 118 | long dcc_capture_maxsize; 119 | 120 | char *dcc_tunnel_incoming; 121 | char *dcc_tunnel_outgoing; 122 | 123 | char *switch_user; 124 | 125 | int motd_logo; 126 | char *motd_file; 127 | int motd_stats; 128 | 129 | int allow_persist; 130 | int allow_jump; 131 | int allow_jump_new; 132 | int allow_host; 133 | int allow_die; 134 | int allow_users; 135 | int allow_kill; 136 | int allow_notify; 137 | 138 | char *password; 139 | struct strlist *servers, *next_server; 140 | struct strlist *masklist; 141 | struct strlist *channels; 142 | 143 | /* Most config file options can be changed by editing the config file and 144 | HUP'ing dircproxy. One or two can be done from the /DIRCPROXY command 145 | though. Always keep the originals. */ 146 | 147 | /* EXPERIMENTAL 148 | * allow dynamic enable GET and SET command to get and set configuration 149 | * option in runtime. usefull if you want to put some configuration option 150 | * inside your irc client. 151 | */ 152 | int allow_dynamic; 153 | 154 | char *orig_local_address; 155 | 156 | struct ircconnclass *next; 157 | } IRCConnClass; 158 | 159 | /* a channel someone is on */ 160 | typedef struct ircchannel { 161 | char *name; 162 | char *key; 163 | int inactive; 164 | int unjoined; 165 | struct logfile log; 166 | 167 | struct ircchannel *next; 168 | } IRCChannel; 169 | 170 | /* a proxied connection */ 171 | typedef struct ircproxy { 172 | int dead; 173 | struct ircconnclass *conn_class; 174 | int die_on_close; 175 | time_t start; 176 | 177 | int client_sock; 178 | int client_status; 179 | SOCKADDR client_addr; 180 | char *client_host; 181 | 182 | int server_sock; 183 | int server_status; 184 | SOCKADDR server_addr; 185 | long server_attempts; 186 | 187 | char *nickname; 188 | char *setnickname; 189 | char *oldnickname; 190 | 191 | char *username; 192 | char *hostname; 193 | char *realname; 194 | char *servername; 195 | char *serverver; 196 | char *serverumodes; 197 | char *servercmodes; 198 | char *serverpassword; 199 | struct strlist *serversupported; 200 | 201 | char *password; 202 | 203 | int allow_motd; 204 | int allow_pong; 205 | int squelch_411; 206 | int expecting_nick; 207 | struct strlist *squelch_modes; 208 | 209 | char *ctcp_userinfo; 210 | char *ctcp_finger; 211 | char *awaymessage; 212 | char *modes; 213 | struct ircchannel *channels; 214 | 215 | char *temp_logdir; 216 | struct logfile private_log, server_log; 217 | 218 | struct ircproxy *next; 219 | } IRCProxy; 220 | 221 | /* a dcc resume */ 222 | struct dcc_resume { 223 | int l_port; 224 | int r_port; 225 | char *id; 226 | char *capfile; 227 | char *rejmsg; 228 | char *fullname; 229 | #ifdef __APPLE__ 230 | u_int32_t size; 231 | #else 232 | uint32_t size; 233 | #endif 234 | struct in_addr r_addr; 235 | struct dcc_resume *next; 236 | }; 237 | 238 | /* states a client can be in */ 239 | #define IRC_CLIENT_NONE 0x00 240 | #define IRC_CLIENT_CONNECTED 0x01 241 | #define IRC_CLIENT_GOTPASS 0x02 242 | #define IRC_CLIENT_GOTNICK 0x04 243 | #define IRC_CLIENT_GOTUSER 0x08 244 | #define IRC_CLIENT_AUTHED 0x10 245 | #define IRC_CLIENT_SENTWELCOME 0x20 246 | #define IRC_CLIENT_ACTIVE 0x3d 247 | 248 | /* Can we send data to the client? */ 249 | #define IS_CLIENT_READY(_c) (((_c)->client_status & 0x1d) == 0x1d) 250 | 251 | /* states a server can be in */ 252 | #define IRC_SERVER_NONE 0x00 253 | #define IRC_SERVER_CREATED 0x01 254 | #define IRC_SERVER_SEEN 0x02 255 | #define IRC_SERVER_CONNECTED 0x04 256 | #define IRC_SERVER_INTRODUCED 0x08 257 | #define IRC_SERVER_GOTWELCOME 0x10 258 | #define IRC_SERVER_ACTIVE 0x1f 259 | 260 | /* Can we send data to the server? */ 261 | #define IS_SERVER_READY(_c) (((_c)->server_status & 0x0c) == 0x0c) 262 | 263 | /* global variables */ 264 | extern struct ircconnclass *connclasses; 265 | 266 | /* functions */ 267 | extern int ircnet_listen(const char *); 268 | extern int ircnet_expunge_proxies(void); 269 | extern void ircnet_flush(void); 270 | extern void ircnet_flush_proxies(struct ircproxy **); 271 | extern void ircnet_flush_connclasses(struct ircconnclass **); 272 | extern void ircnet_freeconnclass(struct ircconnclass *); 273 | extern int ircnet_hooksocket(int); 274 | extern struct ircproxy *ircnet_fetchclass(struct ircconnclass *); 275 | extern struct ircchannel *ircnet_fetchchannel(struct ircproxy *, const char *); 276 | extern int ircnet_addchannel(struct ircproxy *, const char *); 277 | extern int ircnet_delchannel(struct ircproxy *, const char *); 278 | extern int ircnet_channel_mode(struct ircproxy *, struct ircchannel *, 279 | struct ircmessage *, int); 280 | extern struct ircchannel *ircnet_freechannel(struct ircchannel *); 281 | extern int ircnet_rejoin(struct ircproxy *, const char *); 282 | extern int ircnet_dedicate(struct ircproxy *); 283 | extern int ircnet_announce_dedicated(struct ircproxy *); 284 | extern int ircnet_announce_nolisten(struct ircproxy *); 285 | extern int ircnet_announce_status(struct ircproxy *); 286 | 287 | #endif /* __DIRCPROXY_IRC_NET_H */ 288 | -------------------------------------------------------------------------------- /src/help.h: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * help.h 11 | * -- 12 | * @(#) $Id: help.h,v 1.13 2004/02/13 23:39:33 bear Exp $ 13 | * 14 | * This file is distributed according to the GNU General Public 15 | * License. For full details, read the top of 'main.c' or the 16 | * file called COPYING that was distributed with this code. 17 | */ 18 | 19 | #ifndef __DIRCPROXY_HELP_H 20 | #define __DIRCPROXY_HELP_H 21 | 22 | /* help index */ 23 | static char *help_index[] = { 24 | "dircproxy can be controlled using the /DIRCPROXY command.", 25 | "This command takes one or more parameters, the first of", 26 | "which is a command, the rest of which depend on the", 27 | "command chosen.", 28 | "", 29 | "Valid commands:", 30 | 0 31 | }; 32 | static char *help_index_end[] = { 33 | "", 34 | "For more information on a command, use /DIRCPROXY HELP", 35 | "followed by the command", 36 | 0 37 | }; 38 | 39 | /* help help */ 40 | static char *help_help[] = { 41 | "/DIRCPROXY HELP", 42 | "displays general help on dircproxy and a list of valid", 43 | "commands.", 44 | "", 45 | "/DIRCPROXY HELP [command]", 46 | "displays specific help on the requested command.", 47 | 0 48 | }; 49 | 50 | /* help quit */ 51 | static char *help_quit[] = { 52 | "/DIRCPROXY QUIT [quit message]", 53 | "detaches you from dircproxy, and also ends the proxied", 54 | "session to the server. This is the only way to do this.", 55 | "An optional /QUIT message may be supplied, you may need", 56 | "to prefix this with a : if it contains spaces.", 57 | 0 58 | }; 59 | 60 | /* help detach */ 61 | static char *help_detach[] = { 62 | "/DIRCPROXY DETACH [away message]", 63 | "detaches you from dircproxy, and sets an optional away", 64 | "message. This usually has the same effect as simply", 65 | "closing your client, or using your clients /QUIT command.", 66 | "The away message may need to be prefixed with a : if it", 67 | "contains spaces", 68 | 0 69 | }; 70 | 71 | /* help recall */ 72 | static char *help_recall[] = { 73 | "/DIRCPROXY RECALL [from] ", 74 | "/DIRCPROXY RECALL ALL", 75 | "recalls log messages from the private message log", 76 | "file. You can specify the number of lines to recall, and", 77 | "a starting point in the file, or you can specify ALL to", 78 | "recall all log messages", 79 | "", 80 | "/DIRCPROXY RECALL [from] lines>", 81 | "/DIRCPROXY RECALL ALL", 82 | "recalls log messages from the private message log file", 83 | "that were sent by the nickname given. You can specify", 84 | "the number of lines to recall and an optional starting", 85 | "point (in the full log file). You may also specify ALL.", 86 | "", 87 | "/DIRCPROXY RECALL SERVER ", 88 | "/DIRCPROXY RECALL SERVER ALL", 89 | "recalls log messages from the server message log", 90 | "file. You can specify the number of lines to recall, and", 91 | "a starting point in the file, or you can specify ALL to", 92 | "recall all log messages", 93 | "", 94 | "/DIRCPROXY RECALL [from] ", 95 | "/DIRCPROXY RECALL ALL", 96 | "recalls log messages from the channel log specified. You", 97 | "can specify the number of lines to recall and an optional", 98 | "starting point in the file, or you can specify ALL to", 99 | "recall all log messages", 100 | 0 101 | }; 102 | 103 | /* help reload */ 104 | static char *help_reload[] = { 105 | "/DIRCPROXY RELOAD", 106 | "sets the flag to reload the configuration file at the", 107 | "opportunity.", 108 | 0 109 | }; 110 | 111 | /* help persist */ 112 | static char *help_persist[] = { 113 | "/DIRCPROXY PERSIST", 114 | "for use if running dircproxy under inetd or if you have", 115 | "disconnect_on_detach set to yes in the config file.", 116 | "Tells dircproxy you want it to persist with its server", 117 | "connect and allow you to reattach later. It will tell", 118 | "you which hostname and port you should use to reconnect", 119 | "(may not be the same as the one you originally connected", 120 | "to)", 121 | "", 122 | "This command has no effect for normal proxy sessions", 123 | 0 124 | }; 125 | 126 | /* help motd */ 127 | static char *help_motd[] = { 128 | "/DIRCPROXY MOTD", 129 | "displays the dircproxy message of the day that it gives", 130 | "you when you attach", 131 | 0 132 | }; 133 | 134 | /* help die */ 135 | static char *help_die[] = { 136 | "/DIRCPROXY DIE", 137 | "kills the dircproxy process on the server. You won't", 138 | "be able to reconnect after you do this.", 139 | 0 140 | }; 141 | 142 | /* help servers */ 143 | static char *help_servers[] = { 144 | "/DIRCPROXY SERVERS", 145 | "displays a list of servers that dircproxy will cycle upon", 146 | "disconnection. Current server is marked with an arrow", 147 | 0 148 | }; 149 | 150 | /* help jump (with new) */ 151 | static char *help_jump_new[] = { 152 | "/DIRCPROXY JUMP", 153 | "disconnect from the current server and jump to the next", 154 | "server in the /DIRCPROX SERVERS list", 155 | "", 156 | "/DIRCPROXY JUMP ", 157 | "disconnect from the current server and jump to the server", 158 | "in the /DIRCPROXY SERVERS list specified by number", 159 | "", 160 | "/DIRCPROXY JUMP [:[port][:[password]]]", 161 | "disconnect from the current server and jump to the server", 162 | "specified", 163 | 0 164 | }; 165 | 166 | /* help jump (without new) */ 167 | static char *help_jump[] = { 168 | "/DIRCPROXY JUMP", 169 | "disconnect from the current server and jump to the next", 170 | "server in the /DIRCPROX SERVERS list", 171 | "", 172 | "/DIRCPROXY JUMP ", 173 | "disconnect from the current server and jump to the server", 174 | "in the /DIRCPROXY SERVERS list specified by number", 175 | "", 176 | "/DIRCPROXY JUMP [:[port][:[password]]]", 177 | "disconnect from the current server and jump to the server", 178 | "in the /DIRCPROXY SERVERS list specified by the full", 179 | "details", 180 | 0 181 | }; 182 | 183 | /* help host */ 184 | static char *help_host[] = { 185 | "/DIRCPROXY HOST ", 186 | "disconnect from the current server, and reconnect to it", 187 | "again with a different locally available hostname. This", 188 | "basically changes the local_address config option on the", 189 | "fly", 190 | "", 191 | "/DIRCPROXY HOST NONE", 192 | "disconnect from the current server, and reconnect to it", 193 | "again with the best available hostname.", 194 | "", 195 | "/DIRCPROXY HOST", 196 | "disconnect from the current server, and reconnect to it", 197 | "again with the hostname originally specified in the", 198 | "local_address config option (if any)", 199 | 0 200 | }; 201 | 202 | /* help status */ 203 | static char *help_status[] = { 204 | "/DIRCPROXY STATUS", 205 | "displays dircproxy status information, great for bug", 206 | "reports!", 207 | 0 208 | }; 209 | 210 | /* help users */ 211 | static char *help_users[] = { 212 | "/DIRCPROXY USERS", 213 | "displays list of users currently using dircproxy", 214 | 0 215 | }; 216 | 217 | /* help kill */ 218 | static char *help_kill[] = { 219 | "/DIRCPROXY KILL ", 220 | "end the proxy session for the user listed in the", 221 | "/DIRCPROXY USERS list specified by number", 222 | "", 223 | "/DIRCPROXY KILL ", 224 | "end the proxy session for the user coming from or connecting", 225 | "to the hostname specified", 226 | "", 227 | "/DIRCPROXY KILL ", 228 | "end the proxy session for the user with the nickname specified", 229 | 0 230 | }; 231 | 232 | /* help notify */ 233 | static char *help_notify[] = { 234 | "/DIRCPROXY NOTIFY ", 235 | "send a notice to the user listed in the", 236 | "/DIRCPROXY USERS list specified by number", 237 | "", 238 | "/DIRCPROXY NOTIFY ", 239 | "send a notice to the user coming from or connecting", 240 | "to the hostname specified", 241 | "", 242 | "/DIRCPROXY NOTIFY ", 243 | "send a notice to the user with the nickname specified", 244 | 0 245 | }; 246 | 247 | /* help get */ 248 | static char *help_get[] = { 249 | "/DIRCPROXY GET ", 250 | "get the value of the parameters specified by name", 251 | 0 252 | }; 253 | 254 | /* help set */ 255 | static char *help_set[] = { 256 | "/DIRCPROXY SET ", 257 | "set the value of the parameters specified by name", 258 | 0 259 | }; 260 | 261 | #endif /* __DIRCPROXY_HELP_H */ 262 | -------------------------------------------------------------------------------- /install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # install - install a program, script, or datafile 3 | 4 | scriptversion=2005-05-14.22 5 | 6 | # This originates from X11R5 (mit/util/scripts/install.sh), which was 7 | # later released in X11R6 (xc/config/util/install.sh) with the 8 | # following copyright and license. 9 | # 10 | # Copyright (C) 1994 X Consortium 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to 14 | # deal in the Software without restriction, including without limitation the 15 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 | # sell copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26 | # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27 | # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # Except as contained in this notice, the name of the X Consortium shall not 30 | # be used in advertising or otherwise to promote the sale, use or other deal- 31 | # ings in this Software without prior written authorization from the X Consor- 32 | # tium. 33 | # 34 | # 35 | # FSF changes to this file are in the public domain. 36 | # 37 | # Calling this script install-sh is preferred over install.sh, to prevent 38 | # `make' implicit rules from creating a file called install from it 39 | # when there is no Makefile. 40 | # 41 | # This script is compatible with the BSD install script, but was written 42 | # from scratch. It can only install one file at a time, a restriction 43 | # shared with many OS's install programs. 44 | 45 | # set DOITPROG to echo to test this script 46 | 47 | # Don't use :- since 4.3BSD and earlier shells don't like it. 48 | doit="${DOITPROG-}" 49 | 50 | # put in absolute paths if you don't have them in your path; or use env. vars. 51 | 52 | mvprog="${MVPROG-mv}" 53 | cpprog="${CPPROG-cp}" 54 | chmodprog="${CHMODPROG-chmod}" 55 | chownprog="${CHOWNPROG-chown}" 56 | chgrpprog="${CHGRPPROG-chgrp}" 57 | stripprog="${STRIPPROG-strip}" 58 | rmprog="${RMPROG-rm}" 59 | mkdirprog="${MKDIRPROG-mkdir}" 60 | 61 | chmodcmd="$chmodprog 0755" 62 | chowncmd= 63 | chgrpcmd= 64 | stripcmd= 65 | rmcmd="$rmprog -f" 66 | mvcmd="$mvprog" 67 | src= 68 | dst= 69 | dir_arg= 70 | dstarg= 71 | no_target_directory= 72 | 73 | usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 74 | or: $0 [OPTION]... SRCFILES... DIRECTORY 75 | or: $0 [OPTION]... -t DIRECTORY SRCFILES... 76 | or: $0 [OPTION]... -d DIRECTORIES... 77 | 78 | In the 1st form, copy SRCFILE to DSTFILE. 79 | In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 80 | In the 4th, create DIRECTORIES. 81 | 82 | Options: 83 | -c (ignored) 84 | -d create directories instead of installing files. 85 | -g GROUP $chgrpprog installed files to GROUP. 86 | -m MODE $chmodprog installed files to MODE. 87 | -o USER $chownprog installed files to USER. 88 | -s $stripprog installed files. 89 | -t DIRECTORY install into DIRECTORY. 90 | -T report an error if DSTFILE is a directory. 91 | --help display this help and exit. 92 | --version display version info and exit. 93 | 94 | Environment variables override the default commands: 95 | CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 96 | " 97 | 98 | while test -n "$1"; do 99 | case $1 in 100 | -c) shift 101 | continue;; 102 | 103 | -d) dir_arg=true 104 | shift 105 | continue;; 106 | 107 | -g) chgrpcmd="$chgrpprog $2" 108 | shift 109 | shift 110 | continue;; 111 | 112 | --help) echo "$usage"; exit $?;; 113 | 114 | -m) chmodcmd="$chmodprog $2" 115 | shift 116 | shift 117 | continue;; 118 | 119 | -o) chowncmd="$chownprog $2" 120 | shift 121 | shift 122 | continue;; 123 | 124 | -s) stripcmd=$stripprog 125 | shift 126 | continue;; 127 | 128 | -t) dstarg=$2 129 | shift 130 | shift 131 | continue;; 132 | 133 | -T) no_target_directory=true 134 | shift 135 | continue;; 136 | 137 | --version) echo "$0 $scriptversion"; exit $?;; 138 | 139 | *) # When -d is used, all remaining arguments are directories to create. 140 | # When -t is used, the destination is already specified. 141 | test -n "$dir_arg$dstarg" && break 142 | # Otherwise, the last argument is the destination. Remove it from $@. 143 | for arg 144 | do 145 | if test -n "$dstarg"; then 146 | # $@ is not empty: it contains at least $arg. 147 | set fnord "$@" "$dstarg" 148 | shift # fnord 149 | fi 150 | shift # arg 151 | dstarg=$arg 152 | done 153 | break;; 154 | esac 155 | done 156 | 157 | if test -z "$1"; then 158 | if test -z "$dir_arg"; then 159 | echo "$0: no input file specified." >&2 160 | exit 1 161 | fi 162 | # It's OK to call `install-sh -d' without argument. 163 | # This can happen when creating conditional directories. 164 | exit 0 165 | fi 166 | 167 | for src 168 | do 169 | # Protect names starting with `-'. 170 | case $src in 171 | -*) src=./$src ;; 172 | esac 173 | 174 | if test -n "$dir_arg"; then 175 | dst=$src 176 | src= 177 | 178 | if test -d "$dst"; then 179 | mkdircmd=: 180 | chmodcmd= 181 | else 182 | mkdircmd=$mkdirprog 183 | fi 184 | else 185 | # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 186 | # might cause directories to be created, which would be especially bad 187 | # if $src (and thus $dsttmp) contains '*'. 188 | if test ! -f "$src" && test ! -d "$src"; then 189 | echo "$0: $src does not exist." >&2 190 | exit 1 191 | fi 192 | 193 | if test -z "$dstarg"; then 194 | echo "$0: no destination specified." >&2 195 | exit 1 196 | fi 197 | 198 | dst=$dstarg 199 | # Protect names starting with `-'. 200 | case $dst in 201 | -*) dst=./$dst ;; 202 | esac 203 | 204 | # If destination is a directory, append the input filename; won't work 205 | # if double slashes aren't ignored. 206 | if test -d "$dst"; then 207 | if test -n "$no_target_directory"; then 208 | echo "$0: $dstarg: Is a directory" >&2 209 | exit 1 210 | fi 211 | dst=$dst/`basename "$src"` 212 | fi 213 | fi 214 | 215 | # This sed command emulates the dirname command. 216 | dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` 217 | 218 | # Make sure that the destination directory exists. 219 | 220 | # Skip lots of stat calls in the usual case. 221 | if test ! -d "$dstdir"; then 222 | defaultIFS=' 223 | ' 224 | IFS="${IFS-$defaultIFS}" 225 | 226 | oIFS=$IFS 227 | # Some sh's can't handle IFS=/ for some reason. 228 | IFS='%' 229 | set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 230 | shift 231 | IFS=$oIFS 232 | 233 | pathcomp= 234 | 235 | while test $# -ne 0 ; do 236 | pathcomp=$pathcomp$1 237 | shift 238 | if test ! -d "$pathcomp"; then 239 | $mkdirprog "$pathcomp" 240 | # mkdir can fail with a `File exist' error in case several 241 | # install-sh are creating the directory concurrently. This 242 | # is OK. 243 | test -d "$pathcomp" || exit 244 | fi 245 | pathcomp=$pathcomp/ 246 | done 247 | fi 248 | 249 | if test -n "$dir_arg"; then 250 | $doit $mkdircmd "$dst" \ 251 | && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 252 | && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 253 | && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 254 | && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 255 | 256 | else 257 | dstfile=`basename "$dst"` 258 | 259 | # Make a couple of temp file names in the proper directory. 260 | dsttmp=$dstdir/_inst.$$_ 261 | rmtmp=$dstdir/_rm.$$_ 262 | 263 | # Trap to clean up those temp files at exit. 264 | trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 265 | trap '(exit $?); exit' 1 2 13 15 266 | 267 | # Copy the file name to the temp name. 268 | $doit $cpprog "$src" "$dsttmp" && 269 | 270 | # and set any options; do chmod last to preserve setuid bits. 271 | # 272 | # If any of these fail, we abort the whole thing. If we want to 273 | # ignore errors from any of these, just make sure not to ignore 274 | # errors from the above "$doit $cpprog $src $dsttmp" command. 275 | # 276 | { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 277 | && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 278 | && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 279 | && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 280 | 281 | # Now rename the file to the real destination. 282 | { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 283 | || { 284 | # The rename failed, perhaps because mv can't rename something else 285 | # to itself, or perhaps because mv is so ancient that it does not 286 | # support -f. 287 | 288 | # Now remove or move aside any old file at destination location. 289 | # We try this two ways since rm can't unlink itself on some 290 | # systems and the destination file might be busy for other 291 | # reasons. In this case, the final cleanup might fail but the new 292 | # file should still install successfully. 293 | { 294 | if test -f "$dstdir/$dstfile"; then 295 | $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 296 | || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 297 | || { 298 | echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 299 | (exit 1); exit 1 300 | } 301 | else 302 | : 303 | fi 304 | } && 305 | 306 | # Now rename the file to the real destination. 307 | $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 308 | } 309 | } 310 | fi || { (exit 1); exit 1; } 311 | done 312 | 313 | # The final little trick to "correctly" pass the exit status to the exit trap. 314 | { 315 | (exit 0); exit 0 316 | } 317 | 318 | # Local variables: 319 | # eval: (add-hook 'write-file-hooks 'time-stamp) 320 | # time-stamp-start: "scriptversion=" 321 | # time-stamp-format: "%:y-%02m-%02d.%02H" 322 | # time-stamp-end: "$" 323 | # End: 324 | -------------------------------------------------------------------------------- /src/irc_prot.c: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * irc_prot.c 11 | * - IRC protocol message parsing 12 | * - IRC x!y@z parsing 13 | * - CTCP stripping and dequoting 14 | * - CTCP message parsing 15 | * - Username sanitisation 16 | * -- 17 | * @(#) $Id: irc_prot.c,v 1.15 2002/12/29 21:30:12 scott Exp $ 18 | * 19 | * This file is distributed according to the GNU General Public 20 | * License. For full details, read the top of 'main.c' or the 21 | * file called COPYING that was distributed with this code. 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include "sprintf.h" 29 | #include "stringex.h" 30 | #include "irc_prot.h" 31 | #include "irc_string.h" 32 | 33 | /* forward declarations */ 34 | static int _ircprot_parse_prefix(char *, struct ircsource *); 35 | static int _ircprot_count_params(char *); 36 | static int _ircprot_get_params(char *, char ***, char ***); 37 | static char *_ircprot_skip_spaces(char *); 38 | static char *_ircprot_ctcpdequote(const char *); 39 | 40 | /* Parse an IRC message. num of params or -1 if no command */ 41 | int ircprot_parsemsg(const char *message, struct ircmessage *msg) { 42 | char *start, *ptr; 43 | 44 | /* Copy the original message as well */ 45 | ptr = start = msg->orig = x_strdup(message); 46 | 47 | /* Begins with a prefix? */ 48 | if (*ptr == ':') { 49 | while (*ptr && (*ptr != ' ')) ptr++; 50 | 51 | msg->src.orig = (char *)malloc(ptr - start); 52 | strncpy(msg->src.orig, start + 1, ptr - start - 1); 53 | msg->src.orig[ptr - start - 1] = 0; 54 | 55 | _ircprot_parse_prefix(msg->src.orig, &(msg->src)); 56 | 57 | ptr = _ircprot_skip_spaces(ptr); 58 | } else { 59 | /* It just came from our peer */ 60 | msg->src.name = msg->src.username = msg->src.hostname = msg->src.orig = 0; 61 | msg->src.fullname = 0; 62 | msg->src.type = IRC_PEER; 63 | } 64 | 65 | /* No command? */ 66 | if (!*ptr) { 67 | free(msg->src.name); 68 | free(msg->src.username); 69 | free(msg->src.hostname); 70 | free(msg->src.fullname); 71 | free(msg->src.orig); 72 | free(msg->orig); 73 | return -1; 74 | } 75 | 76 | /* Take the command off the front */ 77 | start = ptr; 78 | while (*ptr && (*ptr != ' ')) ptr++; 79 | 80 | msg->cmd = (char *)malloc(ptr - start + 1); 81 | strncpy(msg->cmd, start, ptr - start); 82 | msg->cmd[ptr - start] = 0; 83 | 84 | ptr = _ircprot_skip_spaces(ptr); 85 | 86 | /* Now do the parameters */ 87 | msg->numparams = _ircprot_count_params(ptr); 88 | if (msg->numparams) { 89 | msg->params = (char **)malloc(sizeof(char *) * msg->numparams); 90 | msg->paramstarts = (char **)malloc(sizeof(char *) * msg->numparams); 91 | _ircprot_get_params(ptr, &(msg->params), &(msg->paramstarts)); 92 | } else { 93 | msg->params = 0; 94 | msg->paramstarts = 0; 95 | } 96 | 97 | return msg->numparams; 98 | } 99 | 100 | /* Free an IRC message */ 101 | void ircprot_freemsg(struct ircmessage *msg) { 102 | int i; 103 | 104 | for (i = 0; i < msg->numparams; i++) 105 | free(msg->params[i]); 106 | 107 | free(msg->src.name); 108 | free(msg->src.username); 109 | free(msg->src.hostname); 110 | free(msg->src.fullname); 111 | free(msg->src.orig); 112 | free(msg->cmd); 113 | free(msg->params); 114 | free(msg->paramstarts); 115 | free(msg->orig); 116 | } 117 | 118 | /* Parse a prefix from an irc message */ 119 | static int _ircprot_parse_prefix(char *prefix, struct ircsource *source) { 120 | char *str, *ptr; 121 | 122 | str = prefix; 123 | ptr = strchr(str, '!'); 124 | if (ptr) { 125 | source->type = IRC_USER; 126 | source->username = source->hostname = 0; 127 | 128 | source->name = (char *)malloc(ptr - str + 1); 129 | strncpy(source->name, str, ptr - str); 130 | source->name[ptr - str] = 0; 131 | str = ptr + 1; 132 | 133 | ptr = strchr(str, '@'); 134 | if (ptr) { 135 | source->username = (char *)malloc(ptr - str + 1); 136 | strncpy(source->username, str, ptr - str); 137 | source->username[ptr - str] = 0; 138 | str = ptr + 1; 139 | 140 | source->hostname = x_strdup(str); 141 | } else { 142 | source->type = IRC_EITHER; 143 | } 144 | } else { 145 | source->type = IRC_EITHER; 146 | source->username = source->hostname = 0; 147 | source->name = x_strdup(str); 148 | } 149 | 150 | if (source->name && source->username && source->hostname) { 151 | source->fullname = x_sprintf("%s (%s@%s)", source->name, 152 | source->username, source->hostname); 153 | } else { 154 | source->fullname = x_strdup(source->name); 155 | } 156 | 157 | return source->type; 158 | } 159 | 160 | /* Count the number of parameters in an irc message */ 161 | static int _ircprot_count_params(char *message) { 162 | char *ptr; 163 | int count; 164 | 165 | count = 0; 166 | ptr = message; 167 | 168 | while (*ptr) { 169 | count++; 170 | 171 | if (*ptr == ':') break; 172 | while (*ptr && (*ptr != ' ')) ptr++; 173 | ptr = _ircprot_skip_spaces(ptr); 174 | } 175 | 176 | return count; 177 | } 178 | 179 | /* Split an irc message into an array */ 180 | static int _ircprot_get_params(char *message, char ***params, 181 | char ***paramstarts) { 182 | char *ptr, *start; 183 | int param; 184 | 185 | param = 0; 186 | ptr = start = message; 187 | 188 | while (*ptr) { 189 | if (*ptr == ':') { 190 | (*params)[param] = x_strdup(ptr + 1); 191 | (*paramstarts)[param] = ptr + 1; 192 | break; 193 | } else { 194 | (*paramstarts)[param] = start; 195 | 196 | while (*ptr && (*ptr != ' ')) ptr++; 197 | 198 | (*params)[param] = (char *)malloc(ptr - start + 1); 199 | strncpy((*params)[param], start, ptr - start); 200 | (*params)[param][ptr - start] = 0; 201 | 202 | ptr = _ircprot_skip_spaces(ptr); 203 | 204 | param++; 205 | start = ptr; 206 | } 207 | } 208 | 209 | return param + 1; 210 | } 211 | 212 | /* Skip spaces */ 213 | static char *_ircprot_skip_spaces(char *ptr) { 214 | #ifdef OLD_RFC1459_PARAM_SPACE 215 | while (*ptr && (*ptr == ' ')) ptr++; 216 | #else /* OLD_RFC1459_PARAM_SPACE */ 217 | if (*ptr && (*ptr == ' ')) ptr++; 218 | #endif /* OLD_RFC1459_PARAM_SPACE */ 219 | 220 | return ptr; 221 | } 222 | 223 | /* Returns a new string that's the dequoted version of the old one */ 224 | static char *_ircprot_ctcpdequote(const char *msg) { 225 | char *new, *out, *in, *ret; 226 | int quote = 0; 227 | 228 | in = out = new = x_strdup(msg); 229 | while (*in) { 230 | if (quote) { 231 | if (*in == 'a') { 232 | *(out++) = '\\'; 233 | } else { 234 | *(out++) = *in; 235 | } 236 | 237 | quote = 0; 238 | } else { 239 | if (*in == '\\') { 240 | quote = 1; 241 | } else { 242 | *(out++) = *in; 243 | } 244 | } 245 | 246 | in++; 247 | } 248 | *out = 0; 249 | 250 | ret = x_strdup(new); 251 | free(new); 252 | return ret; 253 | } 254 | 255 | /* Strip embedded CTCP messages from a string, placing the new string in the 256 | * newmsg pointer and a strlist of the ctcp's that were found in the list 257 | * pointer */ 258 | void ircprot_stripctcp(const char *msg, char **newmsg, struct strlist **list) { 259 | char *copy, *in, *out, *start = 0; 260 | int ctcp = 0; 261 | 262 | if (list) 263 | *list = 0; 264 | 265 | in = out = copy = x_strdup(msg); 266 | while (*in) { 267 | if (*in == 0x01) { 268 | if (ctcp) { 269 | *(in++) = 0; 270 | out -= strlen(start); 271 | ctcp = 0; 272 | 273 | if (strlen(start + 1) && list) { 274 | struct strlist *s; 275 | 276 | s = (struct strlist *)malloc(sizeof(struct strlist)); 277 | s->str = x_strdup(start + 1); 278 | s->next = 0; 279 | 280 | if (*list) { 281 | struct strlist *ss; 282 | 283 | ss = *list; 284 | while (ss->next) 285 | ss = ss->next; 286 | 287 | ss->next = s; 288 | } else { 289 | *list = s; 290 | } 291 | } 292 | } else { 293 | /* Found start of a CTCP */ 294 | start = in; 295 | ctcp = 1; 296 | *(out++) = *(in++); 297 | } 298 | } else { 299 | *(out++) = *(in++); 300 | } 301 | } 302 | *out = 0; 303 | 304 | if (newmsg) 305 | *newmsg = x_strdup(copy); 306 | free(copy); 307 | } 308 | 309 | /* Parse an CTCP message. num of params or -1 if no command */ 310 | int ircprot_parsectcp(const char *message, struct ctcpmessage *cmsg) { 311 | char *start, *ptr; 312 | 313 | /* Copy the original message as well */ 314 | ptr = start = cmsg->orig = _ircprot_ctcpdequote(message); 315 | 316 | /* No command? */ 317 | if (!*ptr) { 318 | free(cmsg->orig); 319 | return -1; 320 | } 321 | 322 | /* Take the command off the front */ 323 | ptr += strcspn(ptr, " "); 324 | cmsg->cmd = (char *)malloc(ptr - start + 1); 325 | strncpy(cmsg->cmd, start, ptr - start); 326 | cmsg->cmd[ptr - start] = 0; 327 | irc_strupr(cmsg->cmd); 328 | 329 | /* Get the parameters */ 330 | ptr += strspn(ptr, " "); 331 | if (*ptr) { 332 | int p; 333 | 334 | start = ptr; 335 | cmsg->numparams = 0; 336 | while (*ptr) { 337 | ptr += strcspn(ptr, " "); 338 | ptr += strspn(ptr, " "); 339 | cmsg->numparams++; 340 | } 341 | 342 | cmsg->params = (char **)malloc(sizeof(char *) * cmsg->numparams); 343 | cmsg->paramstarts = (char **)malloc(sizeof(char *) * cmsg->numparams); 344 | 345 | p = 0; 346 | ptr = start; 347 | while (*ptr) { 348 | ptr += strcspn(ptr, " "); 349 | 350 | cmsg->paramstarts[p] = start; 351 | cmsg->params[p] = (char *)malloc(ptr - start + 1); 352 | strncpy(cmsg->params[p], start, ptr - start); 353 | cmsg->params[p][ptr - start] = 0; 354 | 355 | ptr += strspn(ptr, " "); 356 | start = ptr; 357 | p++; 358 | } 359 | 360 | } else { 361 | cmsg->numparams = 0; 362 | cmsg->params = 0; 363 | cmsg->paramstarts = 0; 364 | } 365 | 366 | return cmsg->numparams; 367 | } 368 | 369 | /* Free an CTCP message */ 370 | void ircprot_freectcp(struct ctcpmessage *cmsg) { 371 | int i; 372 | 373 | for (i = 0; i < cmsg->numparams; i++) 374 | free(cmsg->params[i]); 375 | 376 | free(cmsg->cmd); 377 | free(cmsg->params); 378 | free(cmsg->paramstarts); 379 | free(cmsg->orig); 380 | } 381 | 382 | /* Strip silly characters from a username */ 383 | char *ircprot_sanitize_username(const char *str) { 384 | char *ret, *out, *in; 385 | 386 | out = in = ret = x_strdup(str); 387 | 388 | while (*in) { 389 | if ((*in >= 'A') && (*in <= 'Z')) { 390 | *(out++) = *in; 391 | } else if ((*in >= 'a') && (*in <= 'z')) { 392 | *(out++) = *in; 393 | } else if ((*in >= '0') && (*in <= '9')) { 394 | *(out++) = *in; 395 | } 396 | 397 | in++; 398 | } 399 | *out = 0; 400 | 401 | if (!strlen(ret)) { 402 | free(ret); 403 | ret = x_strdup(FALLBACK_USERNAME); 404 | } 405 | 406 | return ret; 407 | } 408 | -------------------------------------------------------------------------------- /src/dcc_net.c: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * dcc_net.c 11 | * - Creating new DCC connections 12 | * - Connecting to DCC Senders 13 | * - The list of currently active DCC proxies 14 | * - Miscellaneous DCC functions 15 | * -- 16 | * @(#) $Id: dcc_net.c,v 1.16 2004/04/02 21:34:11 fharvey Exp $ 17 | * 18 | * This file is distributed according to the GNU General Public 19 | * License. For full details, read the top of 'main.c' or the 20 | * file called COPYING that was distributed with this code. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include "net.h" 36 | #include "dns.h" 37 | #include "timers.h" 38 | #include "sprintf.h" 39 | #include "stringex.h" 40 | #include "dcc_chat.h" 41 | #include "dcc_send.h" 42 | #include "dcc_net.h" 43 | 44 | /* forward declarations */ 45 | static int _dccnet_listen(struct dccproxy *, int *, size_t, int *); 46 | static int _dccnet_connect(struct dccproxy *, struct in_addr, int, 47 | int *, size_t, int *); 48 | static int _dccnet_bind(int sock, int *, size_t, int *); 49 | static void _dccnet_timedout(struct dccproxy *, void *); 50 | static void _dccnet_accept(struct dccproxy *, int); 51 | static void _dccnet_free(struct dccproxy *); 52 | 53 | /* list of currently proxied connections */ 54 | static struct dccproxy *proxies = 0; 55 | 56 | /* Create a new DCC connection */ 57 | int dccnet_new(int type, long timeout, int *range, size_t range_sz, 58 | int *lport, struct in_addr addr, int port, 59 | const char *filename, long maxsize, 60 | int (*n_f)(void *, const char *, const char *), 61 | void *n_p, const char *n_msg, uint32_t resume_from) { 62 | struct dccproxy *p; 63 | 64 | p = (struct dccproxy *)malloc(sizeof(struct dccproxy)); 65 | memset(p, 0, sizeof(struct dccproxy)); 66 | p->type = type; 67 | p->bytes_rcvd = resume_from; 68 | /* If we're capturing, we do not need to listen for the client connecting 69 | because its not going to! */ 70 | if (p->type & DCC_SEND_CAPTURE) { 71 | /* Unlink first for security */ 72 | if (!resume_from){ 73 | /* Unlink first for security */ 74 | if (unlink(filename) && (errno != ENOENT)) { 75 | syscall_fail("unlink", filename, 0); 76 | free(p); 77 | return -1; 78 | } 79 | } 80 | 81 | /* Open for writing */ 82 | p->cap_file = fopen(filename, "a"); 83 | if (!p->cap_file) { 84 | syscall_fail("fopen", filename, 0); 85 | free(p); 86 | return -1; 87 | } 88 | 89 | p->cap_filename = x_strdup(filename); 90 | p->bytes_max = maxsize * 1024; 91 | 92 | /* Connect to the sender */ 93 | if (_dccnet_connect(p, addr, port, range, range_sz, lport)) { 94 | fclose(p->cap_file); 95 | free(p->cap_filename); 96 | free(p); 97 | return -1; 98 | } 99 | 100 | } else { 101 | /* Do the connect first, because then that'll hopefully get a port, 102 | which the listen socket can also use later anyway */ 103 | if (_dccnet_connect(p, addr, port, range, range_sz, lport)) { 104 | free(p); 105 | return -1; 106 | } 107 | 108 | /* Now listen, if this fails a bind() then thats fatal */ 109 | if (_dccnet_listen(p, range, range_sz, lport)) { 110 | net_close(&(p->sender_sock)); 111 | free(p); 112 | return -1; 113 | } 114 | } 115 | 116 | p->notify_func = n_f; 117 | p->notify_data = n_p; 118 | if (n_msg) 119 | p->notify_msg = x_strdup(n_msg); 120 | 121 | p->next = proxies; 122 | proxies = p; 123 | 124 | timer_new((void *)p, "timeout", timeout, TIMER_FUNCTION(_dccnet_timedout), 0); 125 | 126 | return 0; 127 | } 128 | 129 | /* Create socket to listen on */ 130 | static int _dccnet_listen(struct dccproxy *p, int *range, size_t range_sz, 131 | int *port) { 132 | int theport; 133 | 134 | p->sendee_sock = net_socket(AF_INET); 135 | if (p->sendee_sock == -1) 136 | return -1; 137 | 138 | if (_dccnet_bind(p->sendee_sock, range, range_sz, &theport)) { 139 | net_close(&(p->sendee_sock)); 140 | return -1; 141 | } 142 | 143 | if (listen(p->sendee_sock, SOMAXCONN)) { 144 | syscall_fail("listen", 0, 0); 145 | net_close(&(p->sendee_sock)); 146 | return -1; 147 | } 148 | 149 | if (port) 150 | *port = theport; 151 | debug("Listening for DCC Sendees on port %d", theport); 152 | p->sendee_status |= DCC_SENDEE_LISTENING; 153 | net_hook(p->sendee_sock, SOCK_LISTENING, (void *)p, 154 | ACTIVITY_FUNCTION(_dccnet_accept), 0); 155 | 156 | return 0; 157 | } 158 | 159 | /* Connect to remote user */ 160 | static int _dccnet_connect(struct dccproxy *p, struct in_addr addr, int port, 161 | int *range, size_t range_sz, int *bindport) { 162 | int theport; 163 | 164 | p->sender_addr.sin_family = AF_INET; 165 | p->sender_addr.sin_addr.s_addr = htonl(addr.s_addr); 166 | p->sender_addr.sin_port = htons(port); 167 | 168 | debug("Connecting to DCC Sender %s:%d", inet_ntoa(p->sender_addr.sin_addr), 169 | ntohs(p->sender_addr.sin_port)); 170 | 171 | p->sender_sock = net_socket(AF_INET); 172 | if (p->sender_sock == -1) 173 | return -1; 174 | 175 | if (_dccnet_bind(p->sender_sock, range, range_sz, &theport)) { 176 | debug("Connecting to DCC Sender from random port"); 177 | } else { 178 | debug("Connecting to DCC Sender from port %d", theport); 179 | if (bindport) 180 | *bindport = theport; 181 | } 182 | 183 | if (connect(p->sender_sock, (struct sockaddr *)&(p->sender_addr), 184 | sizeof(struct sockaddr_in)) && (errno != EINPROGRESS)) { 185 | syscall_fail("connect", inet_ntoa(p->sender_addr.sin_addr), 0); 186 | net_close(&(p->sender_sock)); 187 | return -1; 188 | } 189 | 190 | p->sender_status |= DCC_SENDER_CREATED; 191 | 192 | if (p->type & DCC_SEND) { 193 | net_hook(p->sender_sock, SOCK_CONNECTING, (void *)p, 194 | ACTIVITY_FUNCTION(dccsend_connected), 195 | ERROR_FUNCTION(dccsend_connectfailed)); 196 | } else if (p->type & DCC_CHAT) { 197 | net_hook(p->sender_sock, SOCK_CONNECTING, (void *)p, 198 | ACTIVITY_FUNCTION(dccchat_connected), 199 | ERROR_FUNCTION(dccchat_connectfailed)); 200 | } 201 | 202 | return 0; 203 | } 204 | 205 | /* Bind a dcc socket to one from the allowed range */ 206 | static int _dccnet_bind(int sock, int *range, size_t range_sz, int *port) { 207 | struct sockaddr_in local_addr; 208 | int len; 209 | 210 | local_addr.sin_family = AF_INET; 211 | local_addr.sin_addr.s_addr = INADDR_ANY; 212 | 213 | if (range) { 214 | int bound = 0; 215 | size_t i; 216 | int j; 217 | 218 | for (i = 0; i < range_sz; i += 2) { 219 | for (j = range[i]; j <= range[i + 1]; j++) { 220 | debug("Trying to bind DCC to port %d", j); 221 | local_addr.sin_port = htons(j); 222 | 223 | if (!bind(sock, (struct sockaddr *)&local_addr, 224 | sizeof(struct sockaddr_in))) { 225 | bound = 1; 226 | break; 227 | } 228 | } 229 | 230 | if (bound) 231 | break; 232 | } 233 | 234 | if (!bound) { 235 | debug("No free ports to bind DCC to"); 236 | return -1; 237 | } 238 | 239 | } else { 240 | debug("Binding DCC to random port"); 241 | local_addr.sin_port = 0; 242 | 243 | if (bind(sock, (struct sockaddr *)&local_addr, 244 | sizeof(struct sockaddr_in))) { 245 | syscall_fail("bind", "dcc_listen", 0); 246 | return -1; 247 | } 248 | } 249 | 250 | len = sizeof(struct sockaddr_in); 251 | if (getsockname(sock, (struct sockaddr *)&local_addr, &len)) { 252 | syscall_fail("getsockname", 0, 0); 253 | return -1; 254 | } 255 | 256 | if (port) 257 | *port = ntohs(local_addr.sin_port); 258 | 259 | return 0; 260 | } 261 | 262 | /* Timer hook to check if we've timed out */ 263 | static void _dccnet_timedout(struct dccproxy *p, void *data) { 264 | if ((p->sender_status == DCC_SENDER_ACTIVE) && (p->type & DCC_SEND_CAPTURE)) { 265 | debug("Capturing, and we've connected to sender"); 266 | return; 267 | } 268 | 269 | if (p->sendee_status != DCC_SENDEE_ACTIVE) { 270 | if (p->type & DCC_CHAT) { 271 | net_send(p->sender_sock, "--(%s)-- Timed out awaiting connection from " 272 | "remote peer\n", PACKAGE); 273 | } else if (p->type & DCC_SEND) { 274 | if (p->notify_func) 275 | p->notify_func(p->notify_data, p->notify_msg, 276 | "Timed out awaiting connection from peer"); 277 | } 278 | 279 | } else if (p->sender_status != DCC_SENDER_ACTIVE) { 280 | if (p->type & DCC_CHAT) { 281 | net_send(p->sendee_sock, "--(%s)-- Connection to remote peer timed out\n", 282 | PACKAGE); 283 | 284 | } else if (p->type & DCC_SEND) { 285 | if (p->sender_status & DCC_SENDER_GONE) { 286 | debug("Sender has come and gone, but sendee is connected"); 287 | return; 288 | } else { 289 | if (p->notify_func) 290 | p->notify_func(p->notify_data, p->notify_msg, 291 | "Connection to peer timed out"); 292 | } 293 | } 294 | 295 | } else { 296 | debug("They are talking"); 297 | return; 298 | } 299 | 300 | p->dead = 1; 301 | } 302 | 303 | /* Accept a sendee connection */ 304 | static void _dccnet_accept(struct dccproxy *p, int sock) { 305 | int newsock; 306 | int len; 307 | 308 | /* Accept the connection */ 309 | len = sizeof(struct sockaddr_in); 310 | newsock = accept(sock, (struct sockaddr *)&(p->sendee_addr), &len); 311 | if (newsock == -1) { 312 | syscall_fail("accept", 0, 0); 313 | p->dead = 1; 314 | return; 315 | } 316 | 317 | /* Close the listening socket and make the new socket the sendee */ 318 | net_close(&(p->sendee_sock)); 319 | p->sendee_status &= ~(DCC_SENDEE_LISTENING); 320 | p->sendee_sock = newsock; 321 | net_create(&(p->sendee_sock)); 322 | 323 | if (p->sendee_sock != -1) { 324 | p->sendee_status |= DCC_SENDEE_CONNECTED; 325 | 326 | if (p->type & DCC_SEND) { 327 | dccsend_accepted(p); 328 | } else if (p->type & DCC_CHAT) { 329 | dccchat_accepted(p); 330 | } 331 | 332 | debug("DCC Sendee connected from %s:%d", 333 | inet_ntoa(p->sendee_addr.sin_addr), 334 | ntohs(p->sendee_addr.sin_port)); 335 | } 336 | } 337 | 338 | /* Free a DCC proxy */ 339 | static void _dccnet_free(struct dccproxy *p) { 340 | debug("Freeing DCC proxy"); 341 | 342 | if (p->sender_status & DCC_SENDER_CREATED) 343 | net_close(&(p->sender_sock)); 344 | if (p->sendee_status & DCC_SENDEE_CREATED) 345 | net_close(&(p->sendee_sock)); 346 | 347 | if (p->cap_filename) { 348 | unlink(p->cap_filename); 349 | free(p->cap_filename); 350 | } 351 | if (p->cap_file) 352 | fclose(p->cap_file); 353 | free(p->notify_msg); 354 | free(p->buf); 355 | 356 | dns_delall((void *)p); 357 | timer_delall((void *)p); 358 | 359 | free(p); 360 | } 361 | 362 | /* Get rid of any dead proxies */ 363 | int dccnet_expunge_proxies(void) { 364 | struct dccproxy *p, *l; 365 | 366 | l = 0; 367 | p = proxies; 368 | 369 | while (p) { 370 | if (p->dead) { 371 | struct dccproxy *n; 372 | 373 | n = p->next; 374 | _dccnet_free(p); 375 | 376 | if (l) l->next = n; else proxies = n; 377 | p = n; 378 | } else { 379 | l = p; 380 | p = p->next; 381 | } 382 | } 383 | 384 | return 0; 385 | } 386 | 387 | /* Delete all of the proxies */ 388 | void dccnet_flush(void) { 389 | struct dccproxy *p; 390 | 391 | p = proxies; 392 | 393 | while (p) { 394 | struct dccproxy *n; 395 | 396 | n = p->next; 397 | _dccnet_free(p); 398 | p = n; 399 | } 400 | 401 | proxies = 0; 402 | } 403 | -------------------------------------------------------------------------------- /missing: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Common stub for a few missing GNU programs while installing. 3 | 4 | scriptversion=2005-06-08.21 5 | 6 | # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 7 | # Free Software Foundation, Inc. 8 | # Originally by Fran,cois Pinard , 1996. 9 | 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 2, or (at your option) 13 | # any later version. 14 | 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, write to the Free Software 22 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 23 | # 02110-1301, USA. 24 | 25 | # As a special exception to the GNU General Public License, if you 26 | # distribute this file as part of a program that contains a 27 | # configuration script generated by Autoconf, you may include it under 28 | # the same distribution terms that you use for the rest of that program. 29 | 30 | if test $# -eq 0; then 31 | echo 1>&2 "Try \`$0 --help' for more information" 32 | exit 1 33 | fi 34 | 35 | run=: 36 | 37 | # In the cases where this matters, `missing' is being run in the 38 | # srcdir already. 39 | if test -f configure.ac; then 40 | configure_ac=configure.ac 41 | else 42 | configure_ac=configure.in 43 | fi 44 | 45 | msg="missing on your system" 46 | 47 | case "$1" in 48 | --run) 49 | # Try to run requested program, and just exit if it succeeds. 50 | run= 51 | shift 52 | "$@" && exit 0 53 | # Exit code 63 means version mismatch. This often happens 54 | # when the user try to use an ancient version of a tool on 55 | # a file that requires a minimum version. In this case we 56 | # we should proceed has if the program had been absent, or 57 | # if --run hadn't been passed. 58 | if test $? = 63; then 59 | run=: 60 | msg="probably too old" 61 | fi 62 | ;; 63 | 64 | -h|--h|--he|--hel|--help) 65 | echo "\ 66 | $0 [OPTION]... PROGRAM [ARGUMENT]... 67 | 68 | Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an 69 | error status if there is no known handling for PROGRAM. 70 | 71 | Options: 72 | -h, --help display this help and exit 73 | -v, --version output version information and exit 74 | --run try to run the given command, and emulate it if it fails 75 | 76 | Supported PROGRAM values: 77 | aclocal touch file \`aclocal.m4' 78 | autoconf touch file \`configure' 79 | autoheader touch file \`config.h.in' 80 | automake touch all \`Makefile.in' files 81 | bison create \`y.tab.[ch]', if possible, from existing .[ch] 82 | flex create \`lex.yy.c', if possible, from existing .c 83 | help2man touch the output file 84 | lex create \`lex.yy.c', if possible, from existing .c 85 | makeinfo touch the output file 86 | tar try tar, gnutar, gtar, then tar without non-portable flags 87 | yacc create \`y.tab.[ch]', if possible, from existing .[ch] 88 | 89 | Send bug reports to ." 90 | exit $? 91 | ;; 92 | 93 | -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 94 | echo "missing $scriptversion (GNU Automake)" 95 | exit $? 96 | ;; 97 | 98 | -*) 99 | echo 1>&2 "$0: Unknown \`$1' option" 100 | echo 1>&2 "Try \`$0 --help' for more information" 101 | exit 1 102 | ;; 103 | 104 | esac 105 | 106 | # Now exit if we have it, but it failed. Also exit now if we 107 | # don't have it and --version was passed (most likely to detect 108 | # the program). 109 | case "$1" in 110 | lex|yacc) 111 | # Not GNU programs, they don't have --version. 112 | ;; 113 | 114 | tar) 115 | if test -n "$run"; then 116 | echo 1>&2 "ERROR: \`tar' requires --run" 117 | exit 1 118 | elif test "x$2" = "x--version" || test "x$2" = "x--help"; then 119 | exit 1 120 | fi 121 | ;; 122 | 123 | *) 124 | if test -z "$run" && ($1 --version) > /dev/null 2>&1; then 125 | # We have it, but it failed. 126 | exit 1 127 | elif test "x$2" = "x--version" || test "x$2" = "x--help"; then 128 | # Could not run --version or --help. This is probably someone 129 | # running `$TOOL --version' or `$TOOL --help' to check whether 130 | # $TOOL exists and not knowing $TOOL uses missing. 131 | exit 1 132 | fi 133 | ;; 134 | esac 135 | 136 | # If it does not exist, or fails to run (possibly an outdated version), 137 | # try to emulate it. 138 | case "$1" in 139 | aclocal*) 140 | echo 1>&2 "\ 141 | WARNING: \`$1' is $msg. You should only need it if 142 | you modified \`acinclude.m4' or \`${configure_ac}'. You might want 143 | to install the \`Automake' and \`Perl' packages. Grab them from 144 | any GNU archive site." 145 | touch aclocal.m4 146 | ;; 147 | 148 | autoconf) 149 | echo 1>&2 "\ 150 | WARNING: \`$1' is $msg. You should only need it if 151 | you modified \`${configure_ac}'. You might want to install the 152 | \`Autoconf' and \`GNU m4' packages. Grab them from any GNU 153 | archive site." 154 | touch configure 155 | ;; 156 | 157 | autoheader) 158 | echo 1>&2 "\ 159 | WARNING: \`$1' is $msg. You should only need it if 160 | you modified \`acconfig.h' or \`${configure_ac}'. You might want 161 | to install the \`Autoconf' and \`GNU m4' packages. Grab them 162 | from any GNU archive site." 163 | files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` 164 | test -z "$files" && files="config.h" 165 | touch_files= 166 | for f in $files; do 167 | case "$f" in 168 | *:*) touch_files="$touch_files "`echo "$f" | 169 | sed -e 's/^[^:]*://' -e 's/:.*//'`;; 170 | *) touch_files="$touch_files $f.in";; 171 | esac 172 | done 173 | touch $touch_files 174 | ;; 175 | 176 | automake*) 177 | echo 1>&2 "\ 178 | WARNING: \`$1' is $msg. You should only need it if 179 | you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. 180 | You might want to install the \`Automake' and \`Perl' packages. 181 | Grab them from any GNU archive site." 182 | find . -type f -name Makefile.am -print | 183 | sed 's/\.am$/.in/' | 184 | while read f; do touch "$f"; done 185 | ;; 186 | 187 | autom4te) 188 | echo 1>&2 "\ 189 | WARNING: \`$1' is needed, but is $msg. 190 | You might have modified some files without having the 191 | proper tools for further handling them. 192 | You can get \`$1' as part of \`Autoconf' from any GNU 193 | archive site." 194 | 195 | file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` 196 | test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` 197 | if test -f "$file"; then 198 | touch $file 199 | else 200 | test -z "$file" || exec >$file 201 | echo "#! /bin/sh" 202 | echo "# Created by GNU Automake missing as a replacement of" 203 | echo "# $ $@" 204 | echo "exit 0" 205 | chmod +x $file 206 | exit 1 207 | fi 208 | ;; 209 | 210 | bison|yacc) 211 | echo 1>&2 "\ 212 | WARNING: \`$1' $msg. You should only need it if 213 | you modified a \`.y' file. You may need the \`Bison' package 214 | in order for those modifications to take effect. You can get 215 | \`Bison' from any GNU archive site." 216 | rm -f y.tab.c y.tab.h 217 | if [ $# -ne 1 ]; then 218 | eval LASTARG="\${$#}" 219 | case "$LASTARG" in 220 | *.y) 221 | SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` 222 | if [ -f "$SRCFILE" ]; then 223 | cp "$SRCFILE" y.tab.c 224 | fi 225 | SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` 226 | if [ -f "$SRCFILE" ]; then 227 | cp "$SRCFILE" y.tab.h 228 | fi 229 | ;; 230 | esac 231 | fi 232 | if [ ! -f y.tab.h ]; then 233 | echo >y.tab.h 234 | fi 235 | if [ ! -f y.tab.c ]; then 236 | echo 'main() { return 0; }' >y.tab.c 237 | fi 238 | ;; 239 | 240 | lex|flex) 241 | echo 1>&2 "\ 242 | WARNING: \`$1' is $msg. You should only need it if 243 | you modified a \`.l' file. You may need the \`Flex' package 244 | in order for those modifications to take effect. You can get 245 | \`Flex' from any GNU archive site." 246 | rm -f lex.yy.c 247 | if [ $# -ne 1 ]; then 248 | eval LASTARG="\${$#}" 249 | case "$LASTARG" in 250 | *.l) 251 | SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` 252 | if [ -f "$SRCFILE" ]; then 253 | cp "$SRCFILE" lex.yy.c 254 | fi 255 | ;; 256 | esac 257 | fi 258 | if [ ! -f lex.yy.c ]; then 259 | echo 'main() { return 0; }' >lex.yy.c 260 | fi 261 | ;; 262 | 263 | help2man) 264 | echo 1>&2 "\ 265 | WARNING: \`$1' is $msg. You should only need it if 266 | you modified a dependency of a manual page. You may need the 267 | \`Help2man' package in order for those modifications to take 268 | effect. You can get \`Help2man' from any GNU archive site." 269 | 270 | file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` 271 | if test -z "$file"; then 272 | file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` 273 | fi 274 | if [ -f "$file" ]; then 275 | touch $file 276 | else 277 | test -z "$file" || exec >$file 278 | echo ".ab help2man is required to generate this page" 279 | exit 1 280 | fi 281 | ;; 282 | 283 | makeinfo) 284 | echo 1>&2 "\ 285 | WARNING: \`$1' is $msg. You should only need it if 286 | you modified a \`.texi' or \`.texinfo' file, or any other file 287 | indirectly affecting the aspect of the manual. The spurious 288 | call might also be the consequence of using a buggy \`make' (AIX, 289 | DU, IRIX). You might want to install the \`Texinfo' package or 290 | the \`GNU make' package. Grab either from any GNU archive site." 291 | # The file to touch is that specified with -o ... 292 | file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` 293 | if test -z "$file"; then 294 | # ... or it is the one specified with @setfilename ... 295 | infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` 296 | file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` 297 | # ... or it is derived from the source name (dir/f.texi becomes f.info) 298 | test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info 299 | fi 300 | # If the file does not exist, the user really needs makeinfo; 301 | # let's fail without touching anything. 302 | test -f $file || exit 1 303 | touch $file 304 | ;; 305 | 306 | tar) 307 | shift 308 | 309 | # We have already tried tar in the generic part. 310 | # Look for gnutar/gtar before invocation to avoid ugly error 311 | # messages. 312 | if (gnutar --version > /dev/null 2>&1); then 313 | gnutar "$@" && exit 0 314 | fi 315 | if (gtar --version > /dev/null 2>&1); then 316 | gtar "$@" && exit 0 317 | fi 318 | firstarg="$1" 319 | if shift; then 320 | case "$firstarg" in 321 | *o*) 322 | firstarg=`echo "$firstarg" | sed s/o//` 323 | tar "$firstarg" "$@" && exit 0 324 | ;; 325 | esac 326 | case "$firstarg" in 327 | *h*) 328 | firstarg=`echo "$firstarg" | sed s/h//` 329 | tar "$firstarg" "$@" && exit 0 330 | ;; 331 | esac 332 | fi 333 | 334 | echo 1>&2 "\ 335 | WARNING: I can't seem to be able to run \`tar' with the given arguments. 336 | You may want to install GNU tar or Free paxutils, or check the 337 | command line arguments." 338 | exit 1 339 | ;; 340 | 341 | *) 342 | echo 1>&2 "\ 343 | WARNING: \`$1' is needed, and is $msg. 344 | You might have modified some files without having the 345 | proper tools for further handling them. Check the \`README' file, 346 | it often tells you about the needed prerequisites for installing 347 | this package. You may also peek at any GNU archive site, in case 348 | some other package would contain this missing \`$1' program." 349 | exit 1 350 | ;; 351 | esac 352 | 353 | exit 0 354 | 355 | # Local variables: 356 | # eval: (add-hook 'write-file-hooks 'time-stamp) 357 | # time-stamp-start: "scriptversion=" 358 | # time-stamp-format: "%:y-%02m-%02d.%02H" 359 | # time-stamp-end: "$" 360 | # End: 361 | -------------------------------------------------------------------------------- /src/dns.c: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * 10 | * dns.c 11 | * - non-blocking DNS lookups using callbacks 12 | * - wrappers around /etc/services lookup functions 13 | * 14 | * The non-blocking stuff is a little complex, but it means that the main 15 | * loop can continue while waiting for DNS requests to complete. Completion 16 | * of a DNS request is notified by the child death signal, so it will 17 | * interrupt the main loop to continue where you left off. 18 | * -- 19 | * @(#) $Id: dns.c,v 1.15 2002/12/29 21:30:11 scott Exp $ 20 | * 21 | * This file is distributed according to the GNU General Public 22 | * License. For full details, read the top of 'main.c' or the 23 | * file called COPYING that was distributed with this code. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | #include "sprintf.h" 41 | #include "dns.h" 42 | 43 | /* Structure used to hold information about a dns child */ 44 | struct dnschild { 45 | pid_t pid; 46 | int pipe; 47 | 48 | const char *ip; 49 | 50 | dns_fun_t function; 51 | void *boundto; 52 | void *data; 53 | 54 | struct dnschild *next; 55 | }; 56 | 57 | /* Reply generated by a child */ 58 | struct dnsresult { 59 | int success; 60 | char ip[40]; 61 | char name[DNS_MAX_HOSTLEN]; 62 | }; 63 | 64 | /* forward declarations */ 65 | static void _dns_lookup(const char *, const char *, struct dnsresult *); 66 | static int _dns_startrequest(void *, dns_fun_t, void *, const char *, const char *); 67 | 68 | /* Children */ 69 | static struct dnschild *dnschildren = 0; 70 | 71 | /* Function that looks up DNS request */ 72 | static void _dns_lookup(const char *name, const char *ip, struct dnsresult *res) { 73 | pid_t pid; 74 | 75 | pid = getpid(); 76 | 77 | if (name) { 78 | debug("%d: Looking up IP for '%s'", pid, name); 79 | 80 | if (dns_getip(name, res->ip)) { 81 | strncpy(res->name, name, sizeof(res->name)); 82 | res->name[sizeof(res->name) - 1] = '\0'; 83 | res->success = 1; 84 | } 85 | } else if (ip) { 86 | debug("%d: Lookup up name for '%s'", pid, ip); 87 | 88 | if (dns_getname(ip, res->name, sizeof(res->name))) { 89 | strncpy(res->ip, ip, sizeof(res->ip)); 90 | res->ip[sizeof(res->ip) - 1] = '\0'; 91 | res->success = 1; 92 | } 93 | } 94 | 95 | if (res->success) 96 | debug("%d: Got '%s' (%s)", pid, res->name, res->ip); 97 | else 98 | debug("%d: No result", pid); 99 | } 100 | 101 | /* Function that starts a non-blocking DNS request. */ 102 | static int _dns_startrequest(void *boundto, dns_fun_t function, void *data, 103 | const char *ip, const char *name) 104 | { 105 | struct dnschild *child; 106 | int p[2], wp[2]; 107 | 108 | /* Pipe where the result will be placed on success */ 109 | if (pipe(p)) { 110 | syscall_fail("pipe", "p", 0); 111 | function(boundto, data, 0, 0); 112 | return -1; 113 | } 114 | 115 | /* Pipe to indicate the child can go */ 116 | if (pipe(wp)) { 117 | close(p[0]); 118 | close(p[1]); 119 | syscall_fail("pipe", "wp", 0); 120 | function(boundto, data, 0, 0); 121 | return -1; 122 | } 123 | 124 | /* Allocate and place the child on the list now, to avoid race conditions */ 125 | child = (struct dnschild *)malloc(sizeof(struct dnschild)); 126 | child->pipe = p[0]; 127 | child->function = function; 128 | child->boundto = boundto; 129 | child->ip = ip; 130 | child->data = data; 131 | child->next = dnschildren; 132 | dnschildren = child; 133 | 134 | /* Fork */ 135 | child->pid = fork(); 136 | if (child->pid == -1) { 137 | /* Error */ 138 | syscall_fail("fork", 0, 0); 139 | dnschildren = child->next; 140 | close(p[1]); 141 | close(p[0]); 142 | close(wp[1]); 143 | close(wp[0]); 144 | free(child); 145 | function(boundto, data, 0, 0); 146 | return -1; 147 | 148 | } else if (child->pid) { 149 | /* Parent */ 150 | debug("New DNS process started, pid %d", child->pid); 151 | close(p[1]); 152 | close(wp[0]); 153 | 154 | /* Send go signal */ 155 | write(wp[1], "go", 2); 156 | close(wp[1]); 157 | return 0; 158 | 159 | } else { 160 | struct dnsresult result; 161 | char gobuf[2]; 162 | 163 | close(p[0]); 164 | close(wp[1]); 165 | 166 | /* Use ALARM to do timeouts */ 167 | signal(SIGALRM, SIG_DFL); 168 | alarm(g.dns_timeout); 169 | 170 | /* Wait for a go signal */ 171 | read(wp[0], gobuf, 2); 172 | close(wp[0]); 173 | 174 | /* Do the lookup */ 175 | memset(&result, 0, sizeof(struct dnsresult)); 176 | _dns_lookup(name, ip, &result); 177 | if (result.success) { 178 | /* Succeded, write to our parent and die */ 179 | write(p[1], (void *)&result, sizeof(struct dnsresult)); 180 | exit(0); 181 | } else { 182 | /* Didn't succeed */ 183 | exit(1); 184 | } 185 | } 186 | } 187 | 188 | /* Called to end a DNS request. 0 = Not handled, >0 = Ok, <0 = Error */ 189 | int dns_endrequest(pid_t pid, int status) { 190 | struct dnschild *lastchild, *child; 191 | struct dnsresult result; 192 | char *ip; 193 | char *name; 194 | size_t len; 195 | 196 | /* Check to see whether this was a DNS child */ 197 | child = dnschildren; 198 | lastchild = 0; 199 | while (child) { 200 | if (child->pid == pid) 201 | break; 202 | 203 | lastchild = child; 204 | child = child->next; 205 | } 206 | if (!child) 207 | return 0; 208 | 209 | /* Remove it from the list */ 210 | if (lastchild) { 211 | lastchild->next = child->next; 212 | } else { 213 | dnschildren = child->next; 214 | } 215 | 216 | debug("%d: Was a DNS child, getting result", pid); 217 | 218 | /* Parameters to call function with */ 219 | name = 0; 220 | ip = 0; 221 | 222 | /* Read from pipe if child returned normally */ 223 | if (WIFEXITED(status)) { 224 | if (!WEXITSTATUS(status)) { 225 | len = read(child->pipe, (void *)&result, sizeof(struct dnsresult)); 226 | if (len != sizeof(struct dnsresult)) { 227 | syscall_fail("read", 0, 0); 228 | } else if (result.success) { 229 | debug("%d: Got result", pid); 230 | 231 | ip = result.ip; 232 | name = result.name; 233 | } else { 234 | debug("%d: DNS lookup failed", pid); 235 | } 236 | } else { 237 | debug("%d: DNS lookup returned %d", pid, WEXITSTATUS(status)); 238 | } 239 | } else if (WIFSIGNALED(status)) { 240 | debug("%d: DNS lookup terminated with signal %d", pid, WTERMSIG(status)); 241 | } else { 242 | debug("%d: DNS lookup terminated abnormally", pid); 243 | } 244 | 245 | /* If DNS failed, but we were looking up an IP address, fill that */ 246 | if (!ip && child->ip) { 247 | strcpy(result.ip, child->ip); 248 | ip = result.ip; 249 | } 250 | 251 | /* If DNS failed but we have an IP, fill the name with the IP */ 252 | if (ip && (!name || !strlen(name))) { 253 | strncpy(result.name, ip, sizeof(result.name)); 254 | result.name[sizeof(result.name) - 1] = '\0'; 255 | 256 | debug("%d: Changed name to '%s'", pid, result.name); 257 | name = result.name; 258 | } 259 | 260 | /* Call the function */ 261 | child->function(child->boundto, child->data, ip, name); 262 | 263 | /* Clean up */ 264 | close(child->pipe); 265 | free(child); 266 | 267 | return 1; 268 | } 269 | 270 | /* Kill off any children associated with an ircproxy */ 271 | int dns_delall(void *b) { 272 | struct dnschild *c, *l; 273 | int numdone; 274 | 275 | l = 0; 276 | c = dnschildren; 277 | numdone = 0; 278 | 279 | while (c) { 280 | if (c->boundto == b) { 281 | struct dnschild *n; 282 | 283 | n = c->next; 284 | debug("Killing DNS process %d", c->pid); 285 | kill(c->pid, SIGKILL); 286 | close(c->pipe); 287 | free(c); 288 | 289 | if (l) { 290 | c = l->next = n; 291 | } else { 292 | c = dnschildren = n; 293 | } 294 | } else { 295 | l = c; 296 | c = c->next; 297 | } 298 | } 299 | 300 | return numdone; 301 | } 302 | 303 | /* Kill off ALL dns children */ 304 | void dns_flush(void) { 305 | struct dnschild *c; 306 | 307 | c = dnschildren; 308 | while (c) { 309 | struct dnschild *n; 310 | 311 | n = c->next; 312 | debug("Killing DNS process %d", c->pid); 313 | kill(c->pid, SIGKILL); 314 | close(c->pipe); 315 | free(c); 316 | c = n; 317 | } 318 | 319 | dnschildren = 0; 320 | } 321 | 322 | /* Returns the IP address of a hostname */ 323 | int dns_addrfromhost(void *boundto, void *data, const char *name, dns_fun_t function) { 324 | return _dns_startrequest(boundto, function, data, 0, name); 325 | } 326 | 327 | /* Returns the hostname of an IP address */ 328 | int dns_hostfromaddr(void *boundto, void *data, const char *ip, dns_fun_t function) { 329 | return _dns_startrequest(boundto, function, data, ip, 0); 330 | } 331 | 332 | /* Fill a sockaddr_in from a hostname or hostname:port combo thing */ 333 | int dns_filladdr(void *boundto, const char *name, const char *defaultport, 334 | SOCKADDR *result, dns_fun_t function) { 335 | int ret = 0; 336 | 337 | char host[DNS_MAX_HOSTLEN]; 338 | char portbuf[32]; 339 | int port; 340 | 341 | memset(result, 0, sizeof(SOCKADDR)); 342 | host[0] = '\0'; 343 | /* 1. IPv6 [addr]:port */ 344 | if ((sscanf(name, "[%39[^]]]:%31s", host, portbuf) == 2) || 345 | /* 2. host/ipv4:port */ 346 | (sscanf(name, "%255[^:]:%31s", host, portbuf) == 2)) 347 | port = dns_portfromserv(portbuf); 348 | else { 349 | /* 3. just host name */ 350 | port = dns_portfromserv(defaultport); 351 | strncpy(host, name, sizeof(host)); 352 | host[sizeof(host) - 1] = '\0'; 353 | } 354 | 355 | ret = _dns_startrequest(boundto, function, (void*)port, 0, host); 356 | 357 | return ret; 358 | } 359 | 360 | /* Returns a network port number for a port as a string */ 361 | int dns_portfromserv(const char *serv) { 362 | struct servent *entry; 363 | 364 | entry = getservbyname(serv, "tcp"); 365 | return (entry ? entry->s_port : htons(atoi(serv))); 366 | } 367 | 368 | /* Returns a service name for a network port number */ 369 | char *dns_servfromport(int port) { 370 | struct servent *entry; 371 | char *str; 372 | 373 | entry = getservbyport(port, "tcp"); 374 | if (entry) { 375 | str = x_strdup(entry->s_name); 376 | } else { 377 | str = x_sprintf("%d", port); 378 | } 379 | 380 | return str; 381 | } 382 | 383 | /* look up hostname, place string form of address into ip. 384 | * ip must be long enough to hold the result: IPv6:40, v4:16 385 | * Returns 1 on success */ 386 | int dns_getip(const char *name, char *ip) { 387 | int isip; 388 | 389 | /* save lookup time if name is already in IP form? */ 390 | #ifdef HAVE_IPV6 391 | struct addrinfo *head, hints; 392 | int ret = 0; 393 | 394 | union { 395 | struct in_addr v4addr; 396 | struct in6_addr v6addr; 397 | } addr_u; 398 | 399 | if (inet_pton(AF_INET, name, &addr_u.v4addr) <= 0) 400 | isip = inet_pton(AF_INET6, name, &addr_u.v6addr) > 0 ? 1 : 0; 401 | else 402 | isip = 1; 403 | #else 404 | struct in_addr inp; 405 | struct hostent *host; 406 | 407 | isip = inet_aton(name, &inp); 408 | #endif 409 | 410 | if (isip) { 411 | strcpy(ip, name); 412 | return 1; 413 | } 414 | 415 | #ifdef HAVE_IPV6 416 | head = NULL; 417 | memset (&hints, 0, sizeof (hints)); 418 | hints.ai_family = AF_UNSPEC; 419 | hints.ai_socktype = SOCK_STREAM; 420 | getaddrinfo (name, NULL, &hints, &head); 421 | 422 | if (head) 423 | { 424 | if (getnameinfo(head->ai_addr, head->ai_addrlen, ip, 40, NULL, 425 | 0, NI_NUMERICHOST) == 0) 426 | ret = 1; 427 | freeaddrinfo (head); 428 | } 429 | 430 | return ret; 431 | #else 432 | host = gethostbyname(name); 433 | if (host) 434 | { 435 | char *temp = inet_ntoa(*(struct in_addr *)host->h_addr); 436 | strcpy(ip, temp); 437 | 438 | return 1; 439 | } 440 | 441 | return 0; 442 | #endif 443 | } 444 | 445 | /* look up ip, place up to len bytes of name into name. 446 | * Returns 1 on success */ 447 | int dns_getname(const char *ip, char *name, int len) { 448 | #ifdef HAVE_IPV6 449 | struct addrinfo *head = NULL, hints; 450 | int ret = 0; 451 | 452 | memset (&hints, 0, sizeof (hints)); 453 | hints.ai_family = AF_UNSPEC; 454 | hints.ai_socktype = SOCK_STREAM; 455 | hints.ai_flags = AI_CANONNAME; 456 | getaddrinfo (ip, NULL, &hints, &head); 457 | 458 | if (head) 459 | { 460 | if (getnameinfo(head->ai_addr, head->ai_addrlen, name, len, NULL, 461 | 0, NI_NAMEREQD) == 0) 462 | ret = 1; 463 | 464 | freeaddrinfo (head); 465 | } 466 | 467 | return ret; 468 | #else 469 | struct hostent *host; 470 | struct in_addr addr; 471 | 472 | if (inet_aton (ip, &addr)) { 473 | host = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET); 474 | if (host) { 475 | strncpy(name, host->h_name, len); 476 | name[len - 1] = '\0'; 477 | 478 | return 1; 479 | } 480 | } 481 | 482 | return 0; 483 | #endif 484 | } 485 | -------------------------------------------------------------------------------- /src/irc_net.c: -------------------------------------------------------------------------------- 1 | /* dircproxy 2 | * Copyright (C) 2000-2003 Scott James Remnant 3 | * 4 | * Copyright (C) 2004-2008 Francois Harvey 5 | * 6 | * Copyright (C) 2008-2009 Noel Shrum 7 | * Francois Harvey 8 | * 9 | * irc_net.c 10 | * - Socket to listen for new connections on 11 | * - The list of connection classes 12 | * - The list of currently active proxies 13 | * - Miscellaneous IRC functions 14 | * -- 15 | * @(#) $Id: irc_net.c,v 1.50 2003/12/10 18:55:34 fharvey Exp $ 16 | * 17 | * This file is distributed according to the GNU General Public 18 | * License. For full details, read the top of 'main.c' or the 19 | * file called COPYING that was distributed with this code. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | #include "net.h" 38 | #include "dns.h" 39 | #include "timers.h" 40 | #include "sprintf.h" 41 | #include "irc_log.h" 42 | #include "irc_string.h" 43 | #include "irc_client.h" 44 | #include "irc_server.h" 45 | #include "irc_net.h" 46 | 47 | /* forward declarations */ 48 | static int _ircnet_listen(SOCKADDR *); 49 | static struct ircproxy *_ircnet_newircproxy(void); 50 | static int _ircnet_client_connected(struct ircproxy *); 51 | static void _ircnet_acceptclient(void *, int); 52 | static void _ircnet_freeproxy(struct ircproxy *); 53 | static void _ircnet_rejoin(struct ircproxy *, void *); 54 | 55 | /* list of connection classes */ 56 | struct ircconnclass *connclasses = 0; 57 | 58 | /* whether we are a dedicated proxy or not */ 59 | static int dedicated_proxy = 0; 60 | 61 | /* list of currently proxied connections */ 62 | static struct ircproxy *proxies = 0; 63 | 64 | /* socket we are listening for new client connections on */ 65 | static int listen_sock = -1; 66 | 67 | #define incopy(a) *((struct in_addr *)a) 68 | 69 | /* Create a socket to listen on. 0 = ok, other = error */ 70 | int ircnet_listen(const char *bindaddr) { 71 | SOCKADDR local_addr; 72 | 73 | char host[256]; 74 | char ip[40]; 75 | char portbuf[32]; 76 | unsigned short port; 77 | 78 | /* 1. IPv6 [addr]:port */ 79 | if ((sscanf(bindaddr, "[%39[^]]]:%31s", host, portbuf) == 2) || 80 | /* 2. host/ipv4:port */ 81 | (sscanf(bindaddr, "%255[^:]:%31s", host, portbuf) == 2)) 82 | port = dns_portfromserv(portbuf); 83 | else { 84 | /* 3. port name/number */ 85 | port = dns_portfromserv(bindaddr); 86 | host[0] = '\0'; 87 | } 88 | 89 | if (*host) { 90 | if (!dns_getip(host, ip)) 91 | return -1; 92 | 93 | if (!net_filladdr(&local_addr, ip, port)) 94 | return -1; 95 | } else 96 | if (!net_filladdr(&local_addr, NULL, port)) 97 | return -1; 98 | 99 | return _ircnet_listen(&local_addr); 100 | } 101 | 102 | /* Does the actual work of creating a listen socket. 0 = ok, other = error */ 103 | int _ircnet_listen(SOCKADDR *local_addr) { 104 | int this_sock; 105 | 106 | this_sock = net_socket(SOCKADDR_FAMILY(local_addr)); 107 | if (this_sock == -1) 108 | return -1; 109 | 110 | if (local_addr) { 111 | if (bind(this_sock, (struct sockaddr *)local_addr, 112 | SOCKADDR_LEN(local_addr))) { 113 | syscall_fail("bind", "listen", 0); 114 | net_close(&this_sock); 115 | return -1; 116 | } 117 | } 118 | 119 | if (listen(this_sock, SOMAXCONN)) { 120 | syscall_fail("listen", 0, 0); 121 | net_close(&this_sock); 122 | return -1; 123 | } 124 | 125 | if (listen_sock != -1) { 126 | debug("Closing existing listen socket %d", listen_sock); 127 | net_close(&listen_sock); 128 | } 129 | debug("Listening on socket %d", this_sock); 130 | listen_sock = this_sock; 131 | net_hook(listen_sock, SOCK_LISTENING, 0, 132 | ACTIVITY_FUNCTION(_ircnet_acceptclient), 0); 133 | 134 | return 0; 135 | } 136 | 137 | /* Creates a new ircproxy structure */ 138 | static struct ircproxy *_ircnet_newircproxy(void) { 139 | struct ircproxy *p; 140 | 141 | p = (struct ircproxy *)malloc(sizeof(struct ircproxy)); 142 | memset(p, 0, sizeof(struct ircproxy)); 143 | 144 | return p; 145 | } 146 | 147 | /* Finishes off the creation of an ircproxy structure */ 148 | static int _ircnet_client_connected(struct ircproxy *p) { 149 | p->next = proxies; 150 | proxies = p; 151 | 152 | return ircclient_connected(p); 153 | } 154 | 155 | 156 | /* Creates a client hooked onto a socket */ 157 | int ircnet_hooksocket(int sock) { 158 | struct ircproxy *p; 159 | int len; 160 | 161 | p = _ircnet_newircproxy(); 162 | p->client_sock = sock; 163 | 164 | len = sizeof(SOCKADDR); 165 | if (getpeername(p->client_sock, (struct sockaddr *)&(p->client_addr), &len)) { 166 | syscall_fail("getpeername", "", 0); 167 | free(p); 168 | return -1; 169 | } 170 | 171 | p->die_on_close = 1; 172 | net_create(&(p->client_sock)); 173 | 174 | if (p->client_sock != -1) { 175 | return _ircnet_client_connected(p); 176 | } else { 177 | free(p); 178 | return -1; 179 | } 180 | } 181 | 182 | /* Accept a client. */ 183 | static void _ircnet_acceptclient(void *data, int sock) { 184 | struct ircproxy *p; 185 | int len; 186 | 187 | p = _ircnet_newircproxy(); 188 | 189 | len = sizeof(SOCKADDR); 190 | p->client_sock = accept(sock, (struct sockaddr *)&(p->client_addr), &len); 191 | if (p->client_sock == -1) { 192 | syscall_fail("accept", 0, 0); 193 | free(p); 194 | return; 195 | } 196 | net_create(&(p->client_sock)); 197 | 198 | if (p->client_sock != -1) { 199 | _ircnet_client_connected(p); 200 | } else { 201 | free(p); 202 | } 203 | return; 204 | } 205 | 206 | /* Fetch a proxy for a connection class if one exists */ 207 | struct ircproxy *ircnet_fetchclass(struct ircconnclass *class) { 208 | struct ircproxy *p; 209 | 210 | p = proxies; 211 | while (p) { 212 | if (!p->dead && (p->conn_class == class)) 213 | return p; 214 | p = p->next; 215 | } 216 | 217 | return 0; 218 | } 219 | 220 | /* Fetch a channel from a proxy */ 221 | struct ircchannel *ircnet_fetchchannel(struct ircproxy *p, const char *name) { 222 | struct ircchannel *c; 223 | 224 | c = p->channels; 225 | while (c) { 226 | if (!irc_strcasecmp(c->name, name)) 227 | return c; 228 | 229 | c = c->next; 230 | } 231 | 232 | return 0; 233 | } 234 | 235 | /* Add a channel to a proxy */ 236 | int ircnet_addchannel(struct ircproxy *p, const char *name) { 237 | struct ircchannel *c; 238 | 239 | if (ircnet_fetchchannel(p, name)) 240 | return 0; 241 | 242 | c = (struct ircchannel *)malloc(sizeof(struct ircchannel)); 243 | memset(c, 0, sizeof(struct ircchannel)); 244 | c->name = x_strdup(name); 245 | debug("Joined channel '%s'", c->name); 246 | 247 | if (p->channels) { 248 | struct ircchannel *cc; 249 | 250 | cc = p->channels; 251 | while (cc->next) 252 | cc = cc->next; 253 | 254 | cc->next = c; 255 | } else { 256 | p->channels = c; 257 | } 258 | 259 | /* Intialise the channel log */ 260 | irclog_init(p, c->name); 261 | 262 | /* Open the channel log */ 263 | if (p->conn_class->chan_log_enabled && p->conn_class->chan_log_always) { 264 | if (irclog_open(p, c->name)) 265 | ircclient_send_channotice(p, c->name, 266 | "(warning) Unable to log channel: %s", c->name); 267 | } 268 | 269 | return 0; 270 | } 271 | 272 | /* Remove a channel from a proxy */ 273 | int ircnet_delchannel(struct ircproxy *p, const char *name) { 274 | struct ircchannel *c, *l; 275 | 276 | l = 0; 277 | c = p->channels; 278 | 279 | debug("Parted channel '%s'", name); 280 | 281 | while (c) { 282 | if (!irc_strcasecmp(c->name, name)) { 283 | if (l) { 284 | l->next = c->next; 285 | } else { 286 | p->channels = c->next; 287 | } 288 | 289 | ircnet_freechannel(c); 290 | return 0; 291 | } else { 292 | l = c; 293 | c = c->next; 294 | } 295 | } 296 | 297 | debug(" (which didn't exist)"); 298 | return -1; 299 | } 300 | 301 | /* Got a channel mode change */ 302 | int ircnet_channel_mode(struct ircproxy *p, struct ircchannel *c, 303 | struct ircmessage *msg, int modes) { 304 | int add = 1; 305 | int param; 306 | char *ptr; 307 | 308 | if (msg->numparams < (modes + 1)) 309 | return -1; 310 | 311 | debug("Channel '%s' mode change '%s'", c->name, msg->paramstarts[modes]); 312 | ptr = msg->params[modes]; 313 | param = modes + 1; 314 | 315 | while (*ptr) { 316 | switch (*ptr) { 317 | case '+': 318 | add = 1; 319 | break; 320 | case '-': 321 | add = 0; 322 | break; 323 | /* RFC2812 modes that have a parameter */ 324 | case 'O': 325 | case 'o': 326 | case 'v': 327 | case 'b': 328 | case 'e': 329 | case 'I': 330 | case 'l': 331 | param++; 332 | break; 333 | /* Channel key */ 334 | case 'k': 335 | if (add) { 336 | if (msg->numparams >= (param + 1)) { 337 | debug("Set channel '%s' key '%s'", c->name, msg->params[param]); 338 | free(c->key); 339 | c->key = x_strdup(msg->params[param]); 340 | } else { 341 | debug("Bad mode from server, said +k without a key"); 342 | } 343 | } else if (c->key) { 344 | debug("Remove channel '%s' key"); 345 | free(c->key); 346 | c->key = 0; 347 | } 348 | param++; 349 | break; 350 | } 351 | 352 | ptr++; 353 | } 354 | 355 | return 0; 356 | } 357 | 358 | /* Free an ircchannel structure, returns the next */ 359 | struct ircchannel *ircnet_freechannel(struct ircchannel *chan) { 360 | struct ircchannel *ret; 361 | 362 | ret = chan->next; 363 | 364 | irclog_free(&(chan->log)); 365 | free(chan->name); 366 | free(chan->key); 367 | free(chan); 368 | 369 | return ret; 370 | } 371 | 372 | /* Free an ircproxy structure */ 373 | static void _ircnet_freeproxy(struct ircproxy *p) { 374 | debug("Freeing proxy"); 375 | 376 | if (p->server_status & IRC_SERVER_CONNECTED) { 377 | ircserver_send_command(p, "QUIT", 378 | ":Terminated with extreme prejudice - %s %s", 379 | PACKAGE, VERSION); 380 | ircserver_close_sock(p); 381 | } 382 | 383 | if (p->client_status & IRC_CLIENT_CONNECTED) { 384 | ircclient_send_error(p, "dircproxy going bye-bye"); 385 | ircclient_close(p); 386 | } 387 | 388 | dns_delall((void *)p); 389 | timer_delall((void *)p); 390 | free(p->client_host); 391 | 392 | free(p->nickname); 393 | free(p->setnickname); 394 | free(p->oldnickname); 395 | 396 | free(p->username); 397 | free(p->hostname); 398 | free(p->realname); 399 | free(p->servername); 400 | free(p->serverver); 401 | free(p->serverumodes); 402 | free(p->servercmodes); 403 | free(p->serverpassword); 404 | 405 | free(p->password); 406 | 407 | free(p->awaymessage); 408 | free(p->modes); 409 | 410 | if (p->channels) { 411 | struct ircchannel *c; 412 | 413 | c = p->channels; 414 | while (c) 415 | c = ircnet_freechannel(c); 416 | } 417 | 418 | if (p->squelch_modes) { 419 | struct strlist *s; 420 | 421 | s = p->squelch_modes; 422 | while (s) { 423 | struct strlist *n; 424 | 425 | n = s->next; 426 | free(s->str); 427 | free(s); 428 | s = n; 429 | } 430 | } 431 | 432 | irclog_free(&(p->private_log)); 433 | irclog_free(&(p->server_log)); 434 | irclog_closetempdir(p); 435 | free(p); 436 | } 437 | 438 | /* Get rid of any dead proxies */ 439 | int ircnet_expunge_proxies(void) { 440 | struct ircproxy *p, *l; 441 | 442 | l = 0; 443 | p = proxies; 444 | 445 | while (p) { 446 | if (p->dead) { 447 | struct ircproxy *n; 448 | 449 | n = p->next; 450 | _ircnet_freeproxy(p); 451 | 452 | if (l) { 453 | p = l->next = n; 454 | } else { 455 | p = proxies = n; 456 | } 457 | } else { 458 | l = p; 459 | p = p->next; 460 | } 461 | } 462 | 463 | return 0; 464 | } 465 | 466 | /* Get rid of all the proxies and connection classes */ 467 | void ircnet_flush(void) { 468 | ircnet_flush_proxies(&proxies); 469 | ircnet_flush_connclasses(&connclasses); 470 | } 471 | 472 | /* Get rid of all the proxies */ 473 | void ircnet_flush_proxies(struct ircproxy **p) { 474 | while (*p) { 475 | struct ircproxy *t; 476 | 477 | t = *p; 478 | *p = (*p)->next; 479 | _ircnet_freeproxy(t); 480 | } 481 | *p = 0; 482 | } 483 | 484 | /* Get rid of all the connection classes */ 485 | void ircnet_flush_connclasses(struct ircconnclass **c) { 486 | while (*c) { 487 | struct ircconnclass *t; 488 | 489 | t = *c; 490 | *c = (*c)->next; 491 | ircnet_freeconnclass(t); 492 | } 493 | *c = 0; 494 | } 495 | 496 | /* Free a connection class structure */ 497 | void ircnet_freeconnclass(struct ircconnclass *class) { 498 | struct strlist *s; 499 | 500 | free(class->server_port); 501 | free(class->server_throttle); 502 | free(class->initial_modes); 503 | free(class->drop_modes); 504 | free(class->refuse_modes); 505 | free(class->local_address); 506 | free(class->away_message); 507 | free(class->quit_message); 508 | free(class->attach_message); 509 | free(class->detach_message); 510 | free(class->detach_nickname); 511 | free(class->log_dir); 512 | free(class->log_program); 513 | free(class->dcc_proxy_ports); 514 | free(class->dcc_capture_directory); 515 | free(class->dcc_tunnel_incoming); 516 | free(class->dcc_tunnel_outgoing); 517 | free(class->switch_user); 518 | free(class->motd_file); 519 | 520 | free(class->orig_local_address); 521 | free(class->nickserv_password); 522 | free(class->password); 523 | s = class->servers; 524 | while (s) { 525 | struct strlist *t; 526 | 527 | t = s; 528 | s = s->next; 529 | 530 | free(t->str); 531 | free(t); 532 | } 533 | 534 | s = class->masklist; 535 | while (s) { 536 | struct strlist *t; 537 | 538 | t = s; 539 | s = s->next; 540 | 541 | free(t->str); 542 | free(t); 543 | } 544 | 545 | s = class->channels; 546 | while (s) { 547 | struct strlist *t; 548 | 549 | t = s; 550 | s = s->next; 551 | 552 | free(t->str); 553 | free(t); 554 | } 555 | 556 | free(class); 557 | } 558 | 559 | /* hook to rejoin a channel after a kick */ 560 | static void _ircnet_rejoin(struct ircproxy *p, void *data) { 561 | struct ircchannel *c; 562 | 563 | debug("Rejoining '%s'", (char *)data); 564 | c = ircnet_fetchchannel(p, (char *)data); 565 | if (c) { 566 | if (c->key) { 567 | ircserver_send_command(p, "JOIN", "%s :%s", c->name, c->key); 568 | } else { 569 | ircserver_send_command(p, "JOIN", ":%s", c->name); 570 | } 571 | } else { 572 | ircserver_send_command(p, "JOIN", ":%s", (char *)data); 573 | } 574 | 575 | free(data); 576 | } 577 | 578 | /* Set a timer to rejoin a channel */ 579 | int ircnet_rejoin(struct ircproxy *p, const char *name) { 580 | char *str; 581 | 582 | str = x_strdup(name); 583 | if (p->conn_class->channel_rejoin == 0) { 584 | _ircnet_rejoin(p, (void *)str); 585 | } else if (p->conn_class->channel_rejoin > 0) { 586 | debug("Will rejoin '%s' in %d seconds", str, p->conn_class->channel_rejoin); 587 | timer_new((void *)p, 0, p->conn_class->channel_rejoin, 588 | TIMER_FUNCTION(_ircnet_rejoin), (void *)str); 589 | } 590 | 591 | return 0; 592 | } 593 | 594 | /* Dedicate this proxy and create a listening socket */ 595 | int ircnet_dedicate(struct ircproxy *p) { 596 | struct ircconnclass *c; 597 | 598 | if (dedicated_proxy) 599 | return -1; 600 | 601 | /* Can't dedicate if there are multiple proxies */ 602 | if ((p != proxies) || p->next) { 603 | debug("Multiple active proxies, won't dedicate"); 604 | return -1; 605 | } 606 | 607 | debug("Dedicating proxy"); 608 | 609 | if (_ircnet_listen(0)) 610 | return -1; 611 | 612 | c = connclasses; 613 | while (c) { 614 | if (c == p->conn_class) { 615 | c = c->next; 616 | } else { 617 | struct ircconnclass *t; 618 | 619 | t = c; 620 | c = c->next; 621 | ircnet_freeconnclass(t); 622 | } 623 | } 624 | connclasses = p->conn_class; 625 | connclasses->next = 0; 626 | 627 | /* Okay we're dedicated */ 628 | dedicated_proxy = 1; 629 | ircnet_announce_dedicated(p); 630 | 631 | return 0; 632 | } 633 | 634 | /* send the dedicated listening port to the user */ 635 | int ircnet_announce_dedicated(struct ircproxy *p) { 636 | SOCKADDR listen_addr; 637 | unsigned int port; 638 | int len; 639 | 640 | if (!IS_CLIENT_READY(p)) 641 | return -1; 642 | 643 | len = sizeof(SOCKADDR); 644 | if (!getsockname(listen_sock, (struct sockaddr *)&listen_addr, &len)) { 645 | port = ntohs(SOCKADDR_PORT(&listen_addr)); 646 | } else { 647 | syscall_fail("getsockname", "listen_sock", 0); 648 | return -1; 649 | } 650 | 651 | ircclient_send_notice(p, "Reconnect to this session at %s:%d", 652 | p->hostname, port); 653 | 654 | return 0; 655 | } 656 | 657 | /* tell the client they can't reconnect */ 658 | int ircnet_announce_nolisten(struct ircproxy *p) { 659 | if (!IS_CLIENT_READY(p)) 660 | return -1; 661 | 662 | ircclient_send_notice(p, "You cannot reconnect to this session"); 663 | 664 | return 0; 665 | } 666 | 667 | /* tell the client whether we're dedicated or not listening */ 668 | int ircnet_announce_status(struct ircproxy *p) { 669 | if (p->die_on_close) { 670 | return ircnet_announce_nolisten(p); 671 | } else if (dedicated_proxy) { 672 | return ircnet_announce_dedicated(p); 673 | } else { 674 | return 0; 675 | } 676 | } 677 | --------------------------------------------------------------------------------