[IRC-Dev CVS] [CVS] Module ircdh: Change committed
Brought to you by:
zolty
From: Toni G. <zo...@us...> - 2003-01-18 23:43:02
|
CVSROOT : /cvsroot/irc-dev Module : ircdh Commit time: 2003-01-18 23:43:00 UTC Added files: tools/Bounce/Bounce.cpp tools/Bounce/Bounce.h tools/Bounce/bounce.conf tools/Bounce/build tools/linesync/linesync.conf tools/linesync/linesync.sh Log message: Nuevos utilidades en tools/ ---------------------- diff included ---------------------- Index: ircdh/tools/Bounce/Bounce.cpp diff -u /dev/null ircdh/tools/Bounce/Bounce.cpp:1.1 --- /dev/null Sat Jan 18 15:43:00 2003 +++ ircdh/tools/Bounce/Bounce.cpp Sat Jan 18 15:42:50 2003 @@ -0,0 +1,504 @@ +/* + * IRC - Internet Relay Chat, tools/Bouncer/Bouncer.cpp + * Copyright (C) 1990 Jarkko Oikarinen and + * University of Oulu, Computing Center + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Port Bouncer. + * + * This tool is designed to set up a number of local listening ports, and + * then forward any data recived on those ports, to another host/port combo. + * Each listening port can bounce to a different host/port defined in the + * config file. --Gte + * + * $Id: Bounce.cpp,v 1.1 2003/01/18 23:42:50 zolty Exp $ + * + */ + +#include "Bounce.h" + +int main() { + Bounce* application = new Bounce(); + + /* + * Ignore SIGPIPE. + */ + + struct sigaction act; + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + sigaction(SIGPIPE, &act, 0); + +#ifndef DEBUG + /* + * If we aren't debugging, we might as well + * detach from the console. + */ + + pid_t forkResult = fork() ; + if(forkResult < 0) + { + printf("Unable to fork new process.\n"); + return -1 ; + } + else if(forkResult != 0) + { + printf("Successfully Forked, New process ID is %i.\n", forkResult); + return 0; + } +#endif + + /* + * Create new application object, bind listeners and begin + * polling them. + */ + application->bindListeners(); + + while (1) { + application->checkSockets(); + } +} + +/* + **************************************** + * * + * Bounce class implementation. * + * * + **************************************** + */ + +void Bounce::bindListeners() { +/* + * bindListeners. + * Inputs: Nothing. + * Outputs: Nothing. + * Process: 1. Reads the config file, and.. + * 2. Creates a new listener for each 'P' line found. + * + */ + + FILE* configFd; + char tempBuf[256]; + int localPort = 0; + int remotePort = 0; + char* remoteServer; + char* vHost; + + /* + * Open config File. + */ + + if(!(configFd = fopen("bounce.conf", "r"))) + { + printf("Error, unable to open config file!\n"); + exit(0); + } + + while (fgets(tempBuf, 256, configFd) != NULL) { + if((tempBuf[0] != '#') && (tempBuf[0] != '\r')) { + switch(tempBuf[0]) + { + case 'P': { /* Add new port listener */ + strtok(tempBuf, ":"); + vHost = strtok(NULL, ":"); + localPort = atoi(strtok(NULL, ":")); + remoteServer = strtok(NULL, ":"); + remotePort = atoi(strtok(NULL, ":")); + + Listener* newListener = new Listener(); + strcpy(newListener->myVhost, vHost); + strcpy(newListener->remoteServer, remoteServer); + newListener->remotePort = remotePort; + newListener->localPort = localPort; +#ifdef DEBUG + printf("Adding new Listener: Local: %s:%i, Remote: %s:%i\n", vHost, localPort, remoteServer, remotePort); +#endif + + newListener->beginListening(); + listenerList.insert(listenerList.begin(), newListener); + break; + } + } + } + } +} + +void Bounce::checkSockets() { +/* + * checkSockets. + * Inputs: Nothing. + * Outputs: Nothing. + * Process: 1. Builds up a FD_SET of all sockets we wish to check. + * (Including all listeners & all open connections). + * 2. SELECT(2) the set, and forward/accept as needed. + * + */ + typedef std::list<Listener*> listenerContainer; + typedef listenerContainer::iterator listIter; + + typedef std::list<Connection*> connectionContainer; + typedef connectionContainer::iterator connIter; + + struct timeval tv; + fd_set readfds; + tv.tv_sec = 0; + tv.tv_usec = 1000; + int tempFd = 0; + int tempFd2 = 0; + int highestFd = 0; + int delCheck = 0; + char* tempBuf; + + FD_ZERO(&readfds); + + /* + * Add all Listeners to the set. + */ + + listIter a = listenerList.begin(); + while(a != listenerList.end()) + { + tempFd = (*a)->fd; + FD_SET(tempFd, &readfds); + if (highestFd < tempFd) highestFd = tempFd; + a++; + } + + /* + * Add Local & Remote connections from each + * connection object to the set. + */ + + connIter b = connectionsList.begin(); + while(b != connectionsList.end()) + { + tempFd = (*b)->localSocket->fd; + tempFd2 = (*b)->remoteSocket->fd; + FD_SET(tempFd, &readfds); + if (highestFd < tempFd) highestFd = tempFd; + FD_SET(tempFd2, &readfds); + if (highestFd < tempFd2) highestFd = tempFd2; + b++; + } + + select(highestFd+1, &readfds, NULL, NULL, &tv); + + /* + * Check all connections for readability. + * First check Local FD's. + * If the connection is closed on either side, + * shutdown both sockets, and clean up. + * Otherwise, send the data from local->remote, or + * remote->local. + */ + + b = connectionsList.begin(); + while(b != connectionsList.end()) + { + tempFd = (*b)->localSocket->fd; + + if (FD_ISSET(tempFd, &readfds)) + { + tempBuf = (*b)->localSocket->read(); + if ((tempBuf[0] == 0)) // Connection closed. + { + close((*b)->localSocket->fd); + close((*b)->remoteSocket->fd); +#ifdef DEBUG + printf("Closing FD: %i\n", (*b)->localSocket->fd); + printf("Closing FD: %i\n", (*b)->remoteSocket->fd); +#endif + delete(*b); + delCheck = 1; + b = connectionsList.erase(b); + } else { + (*b)->remoteSocket->write(tempBuf, (*b)->localSocket->lastReadSize); + } + } + + if (!delCheck) b++; + delCheck = 0; + } + + /* + * Now check Remote FD's.. + */ + b = connectionsList.begin(); + while(b != connectionsList.end()) + { + tempFd = (*b)->remoteSocket->fd; + if (FD_ISSET(tempFd, &readfds)) + { + tempBuf = (*b)->remoteSocket->read(); + if ((tempBuf[0] == 0)) // Connection closed. + { + close((*b)->localSocket->fd); + close((*b)->remoteSocket->fd); +#ifdef DEBUG + printf("Closing FD: %i\n", (*b)->localSocket->fd); + printf("Closing FD: %i\n", (*b)->remoteSocket->fd); +#endif + delete(*b); + delCheck = 1; + b = connectionsList.erase(b); + } else { + (*b)->localSocket->write(tempBuf, (*b)->remoteSocket->lastReadSize); + } + } + if (!delCheck) b++; + delCheck = 0; + } + + /* + * Check all listeners for new connections. + */ + + a = listenerList.begin(); + while(a != listenerList.end()) + { + tempFd = (*a)->fd; + if (FD_ISSET(tempFd, &readfds)) + { + recieveNewConnection(*a); + } + a++; + } + +} + +void Bounce::recieveNewConnection(Listener* listener) { +/* + * recieveNewConnection. + * Inputs: A Listener Object. + * Outputs: Nothing. + * Process: 1. Recieves a new connection on a local port, + * and creates a connection object for it. + * 2. Accepts the incomming connection. + * 3. Creates a new Socket object for the remote + * end of the connection. + * 4. Connects up the remote Socket. + * 5. Adds the new Connection object to the + * connections list. + * + */ + + Connection* newConnection = new Connection(); + newConnection->localSocket = listener->handleAccept(); + + Socket* remoteSocket = new Socket(); + newConnection->remoteSocket = remoteSocket; + if(remoteSocket->connectTo(listener->remoteServer, listener->remotePort)) { + connectionsList.insert(connectionsList.begin(), newConnection); + } else { +#ifdef DEBUG + newConnection->localSocket->write("Unable to connect to remote host.\n"); +#endif + close(newConnection->localSocket->fd); + delete(newConnection); + delete(remoteSocket); + } +} + + +/* + **************************************** + * * + * Listener class implementation. * + * * + **************************************** + */ + + +Socket* Listener::handleAccept() { +/* + * handleAccept. + * Inputs: Nothing. + * Outputs: A Socket Object. + * Process: 1. Accept's an incomming connection, + * and returns a new socket object. + */ + + int new_fd = 0; + int sin_size = sizeof(struct sockaddr_in); + + Socket* newSocket = new Socket(); + new_fd = accept(fd, (struct sockaddr*)&newSocket->address, (socklen_t*)&sin_size); + newSocket->fd = new_fd; + return newSocket; +} + +void Listener::beginListening() { +/* + * beginListening. + * Inputs: Nothing. + * Outputs: Nothing. + * Process: 1. Binds the local ports for all the + * Listener objects. + * + */ + + struct sockaddr_in my_addr; + int bindRes; + int optval; + optval = 1; + + fd = socket(AF_INET, SOCK_STREAM, 0); /* Check for no FD's left?! */ + + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(localPort); + my_addr.sin_addr.s_addr = inet_addr(myVhost); + bzero(&(my_addr.sin_zero), 8); + + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + + bindRes = bind(fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)); + if(bindRes == 0) + { + listen(fd, 10); + } else { + /* + * If we can't bind a listening port, we might aswell drop out. + */ + printf("Unable to bind to %s:%i!\n", myVhost, localPort); + exit(0); + } +} + +/* + **************************************** + * * + * Socket class implementation. * + * * + **************************************** + */ + + +Socket::Socket() { +/* + * Socket Constructor. + * Inputs: Nothing. + * Outputs: Nothing. + * Process: Initialises member variables. + * + */ + + fd = -1; + lastReadSize = 0; +} + +int Socket::write(char *message, int len) { +/* + * write. + * Inputs: Message string, and lenght. + * Outputs: Amount written, or 0 on error. + * Process: 1. Writes out 'len' amount of 'message'. + * to this socket. + * + */ + + if (fd == -1) return 0; + + int amount = ::write(fd, message, len); +#ifdef DEBUG + printf("Wrote %i Bytes.\n", amount); +#endif + return amount; +} + +int Socket::write(char *message) { +/* + * write(2). + * Inputs: Message string. + * Outputs: Amount writte, or 0 on error. + * Process: Writes out the whole of 'message'. + * + */ + + if (fd == -1) return 0; + + int amount = ::write(fd, message, strlen(message)); +#ifdef DEBUG + printf("Wrote %i Bytes.\n", amount); +#endif + return amount; +} + + +int Socket::connectTo(char *hostname, unsigned short portnum) { +/* + * connectTo. + * Inputs: Hostname and port. + * Outputs: +ve on success, 0 on failure. + * Process: 1. Connects this socket to remote 'hostname' on + * port 'port'. + * + */ + + struct hostent *hp; + + if ((hp = gethostbyname(hostname)) == NULL) { + return 0; + } + + memset(&address,0,sizeof(address)); + memcpy((char *)&address.sin_addr,hp->h_addr,hp->h_length); + address.sin_family= hp->h_addrtype; + address.sin_port= htons((u_short)portnum); + + if ((fd = socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) + return 0; + + if (connect(fd, (struct sockaddr*)&address, sizeof(address)) < 0) { + close(fd); + fd = -1; + return 0; + } + return(1); +} + +char* Socket::read() { +/* + * read. + * Inputs: Nothing. + * Outputs: char* to static buffer containing data. + * Process: 1. Reads as much as possible from this socket, up to + * 4k. + * + */ + + int amountRead = 0; + static char buffer[4096]; + + amountRead = ::read(fd, &buffer, 4096); + + if ((amountRead == -1)) buffer[0] = '\0'; + buffer[amountRead] = '\0'; + +#ifdef DEBUG + printf("Read %i Bytes.\n", amountRead); +#endif + + /* + * Record this just incase we're dealing with binary data with 0's in it. + */ + lastReadSize = amountRead; + return (char *)&buffer; +} + Index: ircdh/tools/Bounce/Bounce.h diff -u /dev/null ircdh/tools/Bounce/Bounce.h:1.1 --- /dev/null Sat Jan 18 15:43:00 2003 +++ ircdh/tools/Bounce/Bounce.h Sat Jan 18 15:42:50 2003 @@ -0,0 +1,117 @@ +/* + * IRC - Internet Relay Chat, tools/Bouncer/Bouncer.h + * Copyright (C) 1990 Jarkko Oikarinen and + * University of Oulu, Computing Center + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: Bounce.h,v 1.1 2003/01/18 23:42:50 zolty Exp $ + * + */ + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <netdb.h> +#include <ctype.h> +#include <time.h> +#include <stdio.h> +#include <unistd.h> +#include <stdarg.h> +#include <signal.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <netdb.h> +#include <ctype.h> +#include <time.h> +#include <list> +using std::list; + +#define DEBUG + +/* + * "Bounce" Class. + */ + +class Listener; +class Connection; +class Bounce +{ +public: + list<Listener*> listenerList; // List of 'Listeners'. + list<Connection*> connectionsList; // List of 'Connections'. + + void bindListeners(); // Binds Listening Ports. + void checkSockets(); // Polls all sockets. + void recieveNewConnection(Listener*); // Accepts connections. +}; + +/* + * "Socket" Class. + */ + +class Socket +{ +public: + int fd; // File descriptor. + int lastReadSize; // Size of last read buffer. + struct sockaddr_in address; // Socket addr_in struct. + int connectTo(char*, unsigned short); // Connects the socket. + int write(char*, int); // Writes 'int' bytes from message. + int write(char*); // Writes strlen(message). + char* read(); // Reads as much as possible into a 4k buffer. + Socket(); // Constructor. +}; + +/* + * "Listener" Class. + */ + +class Bounce; +class Listener +{ +public: + int fd; // File descriptor. + int remotePort; // Remote port from config. + int localPort; // Local port for binding. + char myVhost[15]; // Vhost to bind locally. + char remoteServer[15]; // Remote server to connect to. + + void beginListening(); // Bind listening ports. + Socket* handleAccept(); // Accept a new connection. +}; + +/* + * "Connection" Class. + * Simply a container for a local/remote Socket pair. + */ + +class Connection +{ +public: + Socket* localSocket; + Socket* remoteSocket; +}; + Index: ircdh/tools/Bounce/bounce.conf diff -u /dev/null ircdh/tools/Bounce/bounce.conf:1.1 --- /dev/null Sat Jan 18 15:43:00 2003 +++ ircdh/tools/Bounce/bounce.conf Sat Jan 18 15:42:50 2003 @@ -0,0 +1,6 @@ +# Format: P:<Local vhost>:<Local Port>:<Remote Address>:<Remote Port> +# IP's only for now :) + +P:192.168.10.5:2000:192.168.10.1:80 +P:192.168.10.5:3000:4.33.94.3:80 +P:192.168.10.5:4000:209.207.224.42:80 Index: ircdh/tools/Bounce/build diff -u /dev/null ircdh/tools/Bounce/build:1.1 --- /dev/null Sat Jan 18 15:43:00 2003 +++ ircdh/tools/Bounce/build Sat Jan 18 15:42:50 2003 @@ -0,0 +1 @@ +g++ -O3 -ggdb -Wall -Wmissing-declarations -o Bounce Bounce.cpp Index: ircdh/tools/linesync/linesync.conf diff -u /dev/null ircdh/tools/linesync/linesync.conf:1.1 --- /dev/null Sat Jan 18 15:43:00 2003 +++ ircdh/tools/linesync/linesync.conf Sat Jan 18 15:42:50 2003 @@ -0,0 +1,15 @@ + +# Configuration for linesync.sh +# +# - This file must be placed in the same directory as ircd.conf +# - Note that all URL's *MUST* have a trailing / +# - Since we are using wget, you could use ftp:// URL's as well if you want to + +# Where do we get our ircd.conf update? +LINE_SERVER="http://some.domain/" + +# Check servers, as many as you like, seperated by spaces +LINE_CHECK="http://host1.other.domain/lsync/ http://host-19.domain-x.net/ http://www.domain.what" + +# What .conf lines are allowed in the downloaded updates? +ALLOWED_LINES="kKQU" Index: ircdh/tools/linesync/linesync.sh diff -u /dev/null ircdh/tools/linesync/linesync.sh:1.1 --- /dev/null Sat Jan 18 15:43:00 2003 +++ ircdh/tools/linesync/linesync.sh Sat Jan 18 15:42:50 2003 @@ -0,0 +1,222 @@ +#!/bin/sh +# linesync.sh, Copyright (c) 2002 Arjen Wolfs +# 20020604, se...@un... +# +# The code contained is in this file is licenced under the terms +# and conditions as specified in the GNU General Public License. +# +# linesync.sh - centralized ircd.conf updates. +# The purpose of this little shell script is to allow a section of an ircd.conf to be +# updated from a central location. Hence it is intended to facilitate the automated +# distribution of k, K, Q, and U lines; or any other .conf lines you may wish to keep +# synchronized accross all servers on a network. +# +# This script will download a file called linesync from a specified web server (see +# below for configuration), and calculate an md5sum from it. It will then download +# a file called linesync.sum from a configurable number of other web servers and +# compare the contents of these files against the checksum calculated. If any of the +# downloaded checksums mismatch, the program will abort. This provides security to +# the centralized update mechanism - in order for it to be compromised, multiple +# web servers would have to compromised. +# +# If all checksums match, the script inspects the .conf lines contained within the +# downloaded file. If any .conf lines are found that are not specifically allowed, +# the program will abort. This will prevent malicious/dangerous .conf lines (such as +# O: or C: lines) from being inserted into ircd.conf. +# +# If all the checks mentioned above are passed, the script checks ircd.conf for a section +# that begins with "# BEGIN LINESYNC", and ends with "# END LINESYNC". The section contained +# between these two comments is the section maintained by this program. If these lines are not +# found in the ircd.conf, they will be appended to it. +# Next, the script will build a new ircd.conf by removing all lines present between the two +# commented lines mentioned above, and replace them with the contents of the file downloaded. +# +# Once this has been completed, ircd.conf is backed up and replaced with the newly built version, +# and ircd will be rehashed. +# +# Configuration: This script requires two parameters - the full path to your ircd.conf, and the +# full path to your ircd.pid. It will look for a configuration file called linesync.conf in the +# same directory as ircd.conf. See the included sample linesync.conf for information on how to +# set it up. Obviously, you will need to have web server(s) to use for the distribution of your +# .conf update and checksums. This script requires the presence of wget and md5sum, and various +# other programs that should be present by default on any Unix system. +# +# This program should be run from crontab, i.e something like: +# 0 0 * * * /home/irc/bin/linesync.sh /home/irc/lib/ircd.conf /home/irc/lib/ircd.pid +# +# This program has been tested on and works on FreeBSD, Solaris, and Linux. +# md5sum is included in GNU textutils. +# +# Good Luck! +# Arjen Wolfs (se...@un...), June 9 2002. +# + +# This checks for the presence of an executable file in $PATH +locate_program() { + if [ ! -x "`which $1 2>&1`" ]; then + echo "You don't seem to have $1. Sorry." + exit 1 + fi +} + +# This checks for the presence of any file +check_file() { + if [ ! -f "$1" ]; then + echo "There doesn't appear to be a $1. Sorry." + exit 1 + fi +} + +# Try to find programs we will need +locate_program wget && locate_program egrep + +# try to find GNU awk +awk_cmd=`which gawk` +if [ $? -ne 0 ]; then + awk_cmd="" +fi + +# try to find an appropriate md5 program +# BSD md5 capability courtesy of spale +md5_cmd=`which md5sum` +if [ -z "$md5_cmd" ]; then + md5_cmd=`which md5` + if [ -z "$md5_cmd" ]; then + echo "No MD5 capable programs found (I looked for md5sum and md5)." + exit + else + md5_cmd="$md5_cmd -q" + fi +fi + +if [ -z "$awk_cmd" ]; then + locate_program awk + is_gawk=`echo | awk --version | head -1 | egrep '^GNU.+$'` + if [ -z "$is_gawk" ]; then + echo "Your version of awk is not GNU awk. Sorry." + exit 1 + fi + awk_cmd="awk" +fi + +# Check for required command line parameters +if [ -z "$1" -o -z "$2" ]; then + echo "Usage: $0 <conf_path> <pid_path>" + echo " <conf_path> Full path to ircd.conf (/home/irc/lib/ircd.conf)" + echo " <pid_path> Full path to ircd.pid (/home/irc/lib/ircd.pid)" + exit 1 +fi + +# check and set up stuff +cpath=$1 +ppath=$2 +check_file $cpath +dpath=`dirname $cpath` +lpath="$dpath/linesync.conf" +check_file $lpath +save_dir=$PWD; cd $dpath +tpath=$PWD; cd $save_dir +tmp_path="$dpath/tmp" +mkdir $tmp_path > /dev/null 2>&1 + +# load and check configuration +. $lpath +if [ -z "$LINE_SERVER" -o -z "$LINE_CHECK" -o -z "$ALLOWED_LINES" ]; then + echo "Please setup $lpath correctly." + exit 1 +fi + +# Not all versions of date support %s, work around it +TS=`date +%Y%m%d%H%M%S` +TMPFILE="$tmp_path/linesync.$TS" +LSFILE="$LINE_SERVER""linesync" +# Attempt to download our .conf update +wget --cache=off --quiet --output-document=$TMPFILE $LSFILE > /dev/null 2>&1 +if [ ! -s "$TMPFILE" ]; then + echo "Unable to retrieve $LSFILE. Sorry." + rm $TMPFILE > /dev/null 2>&1 + exit 1 +fi + +# Check wether the file contains any disallowed .conf lines +bad_lines=`egrep '^[^'$ALLOWED_LINES'#]+' $TMPFILE` +if [ ! -z "$bad_lines" ]; then + echo "The file downloaded in $TMPFILE contains the following disallowed line(s):" + echo $bad_lines + exit 1 +fi + +# check our ircd.conf +ircd_setup=`egrep '^# (BEGIN|END) LINESYNC$' $cpath|wc -l` +if [ $ircd_setup != 2 ]; then + cp $cpath $cpath.orig + echo "Performing initial merge on $cpath, original file saved as $cpath.orig." + + echo "# Do NOT remove the following line, linesync.sh depends on it!" >> $cpath + echo "# BEGIN LINESYNC" >> $cpath + echo "# END LINESYNC" >> $cpath + echo "# Do not remove the previous line, linesync.sh depends on it!" >> $cpath + + # Do an initial merge to remove duplicates + inpath="$tmp_path/linesync.tmp.$TS" + $awk_cmd ' + { + if (!loaded_template) { + command="cat " tempfile; tlines=0; + while ((command | getline avar) > 0) { template[tlines]=avar; tlines++ } + close(command) + loaded_template++ + } + dup_line=0 + for (i=0; i<tlines; i++) { + if (tolower($0)==tolower(template[i])) { dup_line++; break } + } + if (!dup_line) print $0 + } ' tempfile=$TMPFILE < $cpath > $inpath +else + inpath=$cpath +fi + +# Get the checksum +CKSUM=`$md5_cmd $TMPFILE|cut -d' ' -f1` + +check_file="$tmp_path/linesync.sum.$TS" +for ck_server in $LINE_CHECK; do + sumfile="$ck_server""linesync.sum" + wget --cache=off --quiet --output-document=$check_file $sumfile > /dev/null 2>&1 + if [ ! -s "$check_file" ]; then + echo "Unable to retrieve checksum from $sumfile" + exit 1 + fi + if [ "$CKSUM" != "`cat $check_file`" ]; then + echo "Checksum retrieved from $sumfile does not match!" + exit 1 + fi + rm -f $check_file +done +# It all checks out, proceed... + +# Replace the marked block in ircd.conf with the new version + +$awk_cmd ' +$0=="# BEGIN LINESYNC" { chop++; print; next } +$0=="# END LINESYNC" { + command="cat " syncfile + while ((command | getline avar) > 0) { print avar } + close(command) + chop-- +} +{ if (!chop) print $0 } +' syncfile=$TMPFILE < $inpath > $tmp_path/linesync.new.$TS + +# Back up the current ircd.conf and replace it with the new one +cp $cpath $dpath/ircd.conf.bk +cp $tmp_path/linesync.new.$TS $cpath + +# Rehash ircd (without caring wether or not it succeeds) +kill -HUP `cat $ppath 2>/dev/null` > /dev/null 2>&1 + +# (Try to) clean up +rm -rf $tmp_path > /dev/null 2>&1 + +# That's it... ----------------------- End of diff ----------------------- |