diff -BNru iroffer1.2b13/ChangeLog iroffer1.2b13+cpitchfor7/ChangeLog
--- iroffer1.2b13/ChangeLog	Thu Jan  1 01:00:00 1970
+++ iroffer1.2b13+cpitchfor7/ChangeLog	Tue Feb 12 23:15:43 2002
@@ -0,0 +1,103 @@
+cpitchfor7:	Tue Feb 12 22:56:54 GMT 2002	cpitchford
+	*	Fixed bug with advert rehash causing it to only use last
+		advert line in config file.
+
+
+cpitchfor6:	Tue Feb 12 02:01:35 GMT 2002	cpitchford
+	*	%l has been added to the list of tags for the advert
+		directive. It will be replaced with the minimum speed
+
+	*	Added "on" option to NOLIST admin command.. "on" will enable
+		NOLIST indefinitely until NOLIST is called again
+		with either zero or a number of minutes
+
+	*	Added "nolist" config file directives, which will disable
+		listing indefinitely or until nolist admin command is
+		issued to cancel nolist. It also takes an optional 
+		parameter of "-q" to drop list requests silently
+		or of m where it will auto-ban any user for m minutes
+		should they make a list request to the bot, in the same
+		way as the NOLIST admin command
+
+	*	Fixed a BUG in admin.c: void getconfig_set. If line
+		in the configuration file has no parameters (e.g. 
+		"nolist" the "var" and "var2" variables faced a buffer
+		overrun situation, as they are assigned after the
+		terminating NULL character and hence a configfile
+		with a single word on it could potentially lead to
+		a buffer overrun and a SEGV death. This is a bug in
+		iroffer, this patch fixes it.
+
+	*	Added configuration directives "speedwarnings" and 
+		"nospeedwarnings". These two directives turn off the
+		warnings notices sent to users when they reach bandwidth
+		limits
+
+	*	Added SPDWRN admin command with parameter + or - This
+		command turns off the notifications that are sent to a user
+		when they reach bandwidth limits
+
+
+cpitchfor5:		cpitchfor
+	*	%i was added to the humiliate list of replace tags. This
+		will be replaced in the string with the number of
+		minutes the user has been ignored for.
+
+
+cpitchfor4:		cpitchfor
+	*	Humiliate config file directive and admin command was
+		added. Like advert it takes a printf style string
+		in which %u is replaced with the username of a user
+		who has just been auto-banned.
+
+	*	"public" and "nopublic" config file directives were
+		added to allow the ability to control how the bot
+		responds to public triggers
+
+	*	the ignore admin command now accepts network ranges
+		in the form of strings starting with "*"
+		A hostname is checked to see if it ends with a network
+		range (excluding the prefixing *) to determine
+		a match
+	*	!strcmp was replaced with isbanned to determine
+		if a hostname matched an ignore entry to ensure
+		network ranges are catered for
+
+
+cpitchfor3:		cpitchfor
+	*	When a user was banned public triggers failed. This was
+		fixed
+
+	*	advert lines were silently unlinked and therefore caused
+		memory leaks. (Thanks to FarFetch'd for fix)
+
+	*	Files were not closed after finished reading. This is
+		an actual bug in iroffer. This patch fixes it.
+		(Thanks to FarFetch'd for fix)
+
+
+cpitchfor2:		cpitchfor
+	*	PUBLIC admin command added to toggle whether the bot will
+		respond to public messages, and public triggers (/CTCP)
+		using the admin command PUBLIC <+|->
+
+
+cpitchfor1:		cpitchfor
+	*	Altered NOLIST function to admin commands.
+		NOLIST now accepts two parameters. first still specifies
+		how long list is disabled, second new parameter specifies
+		that the list requests should be silently dropped "-q"
+		or the number of minutes to ignore a user after making
+		a list request. Quiet and banning NOLIST commands will
+		also drop the list command without queuing it for
+		processing.
+
+	* 	Added config file directive for custom adverts
+		Advert when used (multiple times also) will define
+		a printf like template for the advert sent out to 
+		channels with the -advert option enabled.
+		The advert is created from the advert lines in the config
+		file in the order they appear.
+		% was chosen as the escape character. The flag letter
+		was taken from the /ctcp status option as mentioned
+		on the iroffer documentation
diff -BNru iroffer1.2b13/README.cpitchfor-patch iroffer1.2b13+cpitchfor7/README.cpitchfor-patch
--- iroffer1.2b13/README.cpitchfor-patch	Thu Jan  1 01:00:00 1970
+++ iroffer1.2b13+cpitchfor7/README.cpitchfor-patch	Tue Feb 12 23:15:43 2002
@@ -0,0 +1,178 @@
+cpitchfor6   2002/02/12				<iroffer@itmakesmemad.com>
+http://iroffer.itmakesmemad.com/
+
+This patch adds a bunch of new features to iroffer. All have been requested
+by faithful people on a channel I frequent. See here for a summary:
+
+XDCC LIST handler:
+------------------
+This is an update to the admin command "NOLIST" and the config file
+directive nolist.
+
+The admin command "NOLIST" can be sent to the bot to control how it will
+react to a xdcc list request:
+
+NOLIST [ <on|m> [-q|n] ]
+
+	NOLIST with no paramters will turn listing back on.
+
+	The first parameter can be "on" or a number.
+		"on":	Turn listing off until it is enabled again
+			with the NOLIST command
+
+		n:	Turn listing off for n minutes
+
+		0:	Turn listing back on
+
+	The second optional parameter can be -q or a number
+		-q:	When a xdcc list request is received quietly
+			drop the request. Do not inform the requesting
+			user that lists have been disabled
+
+		m:	Ban any user that xdcc list requests this bot
+			for m minutes
+
+			if no second paramter is provided, the bot
+			will msg the requesting user to tell them
+			the bot is not accepting list requests.
+			
+
+NOLIST 10		# Will turn off list response for 10 minutes
+
+NOLIST 10 -q		# will turn off list responce for 10 minutes and
+			  drop list requests silently. The user will not
+			  get any response from the server at all. -q quiet
+
+NOLIST 10 100		# Will turn off list response for 10 minutes and
+			  auto ban any user who sends a list request for
+			  100 minutes
+
+NOLIST on 1000		# Will turn off listing and ban any requesting
+			  user for 1000 minutes
+
+The nolist directive has also been added to the configuration file
+
+nolist			# turns off listing
+
+nolist -q		# turns off listing and quietly drop list requests
+			  does NOT inform the user that lists have been
+			  disabled
+
+nolist 1000		# turns off listing and bans any user making a list
+			# request for 1000 minutes.
+
+
+
+Humiliate the user autobanned
+----------------------------
+You can set either as an admin command or in the config file a message to be
+sent to the channels the bot sits on in the event it should auto-ban a user
+
+humiliate I've just banned %u for %t for being naughty
+
+should cpitchfor send a xdcc list when nolist+ban is on the channel would
+see:
+
+<yourbot> I've just banned cpitchfor for 10 minutes for being naughty
+
+
+
+Custom Ads:
+-----------
+This is an additional flag to the channel directive in the configuration
+file:
+
+channel #mychannel -plist 30 -pformat summary -advert
+
+This instructs the bot that when sending an advert to the channel it should
+send a "custom" advert defined in the directive advert:
+
+
+advert This is the first line of the advert
+advert This is the second line of the advert
+advert 3rd line: SLOTS:[%a/%b]  QUEUE:[%c/%d]
+advert 4th line: Record Speed: %g  Total Offered: %x
+
+
+a % is a special character, much like in printf. It will be replaced with
+values as the advert is sent for example the above example would send
+
+<mybot> This is the first line of the advert
+<mybot> This is the second line of the advert
+<mybot> 3rd line: SLOTS:[4/10]  QUEUE:[0/0]
+<mybot> 4th line: Record Speed: 1245.3K/s  Total Offered: 3223.3 MB
+
+If a channel has a "-advert" flag but there are no "advert" lines defined in
+the config file, the bot will not advertise in that channel
+
+The conversions are as follows:
+
+%a	number of slots in use 
+%b	total slots 
+%c	number in main queue 
+%d	size of main queue 
+%e	number in pack queue 
+%f	size of pack queue 
+%g	pack speed record (K/sec) 
+%h	number of lines in send to server queue 
+%i	amount of data sent to network in past 120 seconds (K) 
+%j	average bandwidth of past 120 seconds (K/sec) 
+%k	record average bandwidth (K/sec) 
+%l	minimum bandwith required
+%w	number of packs offered 
+%x	total size of offered packs (MB) 
+%y	total completed transfers
+%z	total transfered (MB)
+%%	a single "%"
+
+
+
+Public Triggers:
+----------------
+iroffer will respond to public triggers such as "xdcc list" or /ctcp
+#channel ping. The admin command "public" can control this functionality
+
+public -
+	will turn off the ability to respond to any public trigger
+
+public +
+	will turn it back on again
+
+you can set the default in you config file with either
+
+public	
+	# react to public triggers
+
+nopublic
+	# dont react to public triggers
+
+
+
+Baning Network ranges:
+----------------------
+ignore 10 cptf-adsl.demon.co.uk
+	will ignore all connections from cptf-adsl.demon.co.uk
+
+ignore 10 *.demon.co.uk
+	will ignore all connections from ANY host ending in .demon.co.uk
+
+
+
+Bandwidth Warning Notices
+-------------------------
+
+When a user is downloading a pack with bandwidth limits (or from a bot with 
+bandwidth limits) iroffer will send the user a warning regarding bandwidth
+limits and how much bandwidth they are using. This can now be controlled
+with these functions:
+
+SPDWRN Admin command
+
+	SPDWRN +	Enable bandwidth warning notices
+	SPDWRN -	Disable bandwidth warning notices
+
+Configuration file directives:
+
+speedwarnings		Enable bandwidth warning notices
+nospeedwarnings		Disable bandwidth warning notices
+
diff -BNru iroffer1.2b13/sample.config iroffer1.2b13+cpitchfor7/sample.config
--- iroffer1.2b13/sample.config	Sat Nov 10 17:06:40 2001
+++ iroffer1.2b13+cpitchfor7/sample.config	Tue Feb 12 23:15:43 2002
@@ -109,13 +109,15 @@
 ###                         - channels (upto 50) -                         ###
 ### channel format:                                                        ###
 ### "channel <channel> [-plist <time>]                                     ###
-###    [-pformat <full|minimal|summary>] [-key <key>] "                    ###
+###    [-pformat <full|minimal|summary>] [-key <key>] [-advert] "          ###
 ### plist: time is number of minutes between plists.                       ###
 ### pformat: full is normal and default if pformat is not used             ###
 ###          minimal is similar to full but removes some lines             ###
 ###          summary displays only a 2 line summary                        ###
 ### key:     for +k channels, the key specified is used when joining       ###
 ### using same or multiples of the same number plist time is recomended    ###
+### advert: This channel will received a customised advert in the format
+###          defined by the advert directive
 channel #chan01
 channel #chan02 -plist 14
 channel #chan03 -plist 28 -pformat minimal
@@ -123,6 +125,74 @@
 
 
 ##############################################################################
+###                               - advert -                               ###
+### advert format:                                                         ###
+### "advert line 1 format"                                                 ###
+### "advert line 2 format"                                                 ###
+### "advert line n format"                                                 ###
+### The advert lines will be combined to form you channel advert           ###
+### Certain characters will be replaced by values:                         ###
+###    %a      number of slots in use                                      ###
+###    %b      total slots                                                 ###
+###    %c      number in main queue                                        ###
+###    %d      size of main queue                                          ###
+###    %e      number in pack queue                                        ###
+###    %f      size of pack queue                                          ###
+###    %g      pack speed record (K/sec)                                   ###
+###    %h      number of lines in send to server queue                     ###
+###    %i      amount of data sent to network in past 120 seconds (K)      ###
+###    %j      average bandwidth of past 120 seconds (K/sec)               ###
+###    %k      record average bandwidth (K/sec)                            ###
+###    %l      required minimum download bandwidth                         ###
+###    %w      number of packs offered                                     ###
+###    %x      total size of offered packs (MB)                            ###
+###    %y      total completed transfers                                   ###
+###    %z      total transfered (MB)                                       ###
+###    %%      a single "%"                                                ###
+
+
+advert my special bot Slots [%a/%b]
+advert queue [%c/%b] %x offered in %w packs
+
+
+##############################################################################
+###                              - nolist -                                ###
+### nolist format:                                                         ###
+### [-q|n]                                                                 ###
+### This function will control how the bot responds to list commands       ###
+### No parameters means the bot will not serve lists, instead it will      ###
+### inform the user lists are disabled                                     ###
+### -q will quietly drop any list request without processing them. The     ###
+### user will not see a response                                           ###
+### n, being a number, will ban any user making a list request to the bot  ###
+### for n minutes                                                          ###
+
+nolist -q
+
+
+
+##############################################################################
+###                             - humiliate -                              ###
+### humiliate format:                                                      ###
+### [message]                                                              ###
+### When a user is autobanned, this message will be sent to the channels   ###
+### as with the advert directive, %u will be replaced with the nick of     ###
+### the person being banned and %i will be replaced with the time before   ###
+### the ban is lifted                                                      ###
+
+humiliate %u has been banned for %i
+
+##############################################################################
+###                              - public -                                ###
+### public|nopublic:                                                       ###
+### sets the default reaction to public triggers. public means the bot     ###
+### responed to public triggers and nopublic means the bot will not        ###
+
+nopublic
+
+
+
+##############################################################################
 ###                          - user information -                          ###
 user_nick nickDCC
 user_realname NAME
@@ -213,8 +283,8 @@
 ### if yes, xdcc list and/or xdcc send will be restricted to users who are ###
 ### on a known channel. If a user is not on one of the known channels they ###
 ### will not be able to list and/or get packs                              ###
-restrictlist no
-restrictsend no
+restrictlist yes
+restrictsend yes
 
 
 ##############################################################################
diff -BNru iroffer1.2b13/src/admin.c iroffer1.2b13+cpitchfor7/src/admin.c
--- iroffer1.2b13/src/admin.c	Sat Nov 10 17:06:40 2001
+++ iroffer1.2b13+cpitchfor7/src/admin.c	Tue Feb 12 23:15:43 2002
@@ -73,6 +73,9 @@
 static void u_crash(const userinput * const u);
 static void u_chanl(const userinput * const u);
 
+static void u_public(const userinput * const u);
+static void u_humiliate(const userinput * const u);
+static void u_spdwrn(const userinput * const u);
 
 /* local info */
 static const userinput_parse_t userinput_parse[] = {
@@ -95,7 +98,7 @@
 {2,method_allow_all,u_send,     "SEND","nick n","Sends Pack n to nick"},
 {2,method_allow_all,u_psend,    "PSEND","<channel>","Sends XDCC LIST to <channel>"},
 {2,method_allow_all,u_qsend,    "QSEND",NULL,"Sends Out The First Queued Pack"},
-
+{2,method_allow_all,u_spdwrn,      "SPDWRN","<+|->","Turn on (+) or off (-) the notices sent to users when bandwidth limits are reached"},
 {3,method_allow_all,u_info,     "INFO","n","Show Info for Pack n"},
 {3,method_allow_all,u_remove,   "REMOVE","n","Removes Pack n"},
 {3,method_allow_all,u_renumber, "RENUMBER","x y","Moves Pack x to y"},
@@ -109,15 +112,15 @@
 
 {4,method_allow_all,u_mesg,     "MESG","<message>","Sends msg to all users who are transferring"},
 {4,method_allow_all,u_mesq,     "MESQ","<message>","Sends msg to all users in a queue"},
-{4,method_allow_all,u_ignore,   "IGNORE","n <host>","Ignore <host> (hostname) for n minutes"},
+{4,method_allow_all,u_ignore,   "IGNORE","n [<host>| *<hostmask>]","Ignore <host> (hostname) or any hostname ending in hostmask for n minutes"},
 {4,method_allow_all,u_nosave,   "NOSAVE","n","Disables XDCC AutoSave for next n minutes"},
 {4,method_allow_all,u_nosend,   "NOSEND","n","Disables XDCC Send for next n minutes"},
-{4,method_allow_all,u_nolist,   "NOLIST","n","Disables XDCC List and Plist for next n mins"},
+{4,method_allow_all,u_nolist,   "NOLIST","n [-q|m]","Disables XDCC List and Plist for next n mins and optionally makes output quiet (-q) or bans any user requesting a list for m minutes"},
 {4,method_allow_all,u_msgread,  "MSGREAD",NULL,"Show MSG log"},
 {4,method_allow_all,u_msgdel,   "MSGDEL",NULL,"Delete MSG log"},
 {4,method_allow_all,u_rmul,     "RMUL","<file>","Delete a file in the Upload Dir"},
 {4,method_allow_all,u_raw,      "RAW","<command>","Send <command> to server (RAW IRC)"},
-
+{4,method_allow_all,u_humiliate,      "HUMILIATE","[message]","Will announce this message (%u is replaced with nick and %t is replaced with the ban time) to all channels when user is autobanned by listing server"},
 {5,method_allow_all,u_servers,  "SERVERS",NULL,"Shows the server list"},
 {5,method_allow_all,u_jump,     "JUMP","<num>","Switches to a random server or server <num>"},
 {5,method_allow_all,u_status,   "STATUS",NULL,"Show Useful Information"},
@@ -130,6 +133,7 @@
 {5,method_msg,      u_chatme,   "CHATME",NULL,"Sends you a DCC Chat Request"},
 {5,method_stdin,    u_debug,    "DEBUG","n","Set Debugging to n [0,1,2]"},
 {5,method_allow_all,u_shutdown, "SHUTDOWN","<act>","Shutdown iroffer, <act> is \"now\", \"delayed\", or \"cancel\""},
+{5,method_allow_all,u_public,      "PUBLIC","<+|->","Turn on (+) or off (-) the ability to resond to public triggers"},
 
 {6,method_stdin,    u_crash, "CRASH",NULL,"Cause a segmentation fault"},
 };
@@ -291,6 +295,7 @@
       privmsg(u->snick,"%s",a);
       break;
    case method_xdl_channel_sum:
+   case method_xdl_channel_cust:
       privmsg(u->snick,"%s",a);
       break;
    case method_allow_all:
@@ -350,10 +355,10 @@
       u_respond(u,"Usage: \"HELP <section>\"");
       u_respond(u,"Help Sections Available:");
       u_respond(u,"  Info     - help, xdl, xds, dcl, dcld, trinfo, qul, ignl, listul, chanl");
-      u_respond(u,"  Transfer - close, rmq, rpq, nomin, nomax, send, psend, qsend");
+      u_respond(u,"  Transfer - close, rmq, rpq, nomin, nomax, send, psend, qsend, spdwrn");
       u_respond(u,"  Pack     - info, remove, renumber, add, adddir, chfile, chdesc, chnote, chmins, chmaxs");
-      u_respond(u,"  Misc     - mesg, mesq, ignore, nosave, nosend, nolist, msgread, msgdel, rmul, raw");
-      u_respond(u,"  Bot      - servers, jump, status, rehash, botinfo, memstat, clearrecords, redraw, quit, chatme, debug, shutdown");
+      u_respond(u,"  Misc     - mesg, mesq, ignore, nosave, nosend, nolist, msgread, msgdel, rmul, raw, public, humiliate");
+      u_respond(u,"  Bot      - servers, jump, status, rehash, botinfo, memstat, clearrecords, redraw, quit, chatme, debug, shutdown, public");
       u_respond(u,"For additional help, see the complete documentation at http://iroffer.org/");
       return;
       }
@@ -394,9 +399,9 @@
    }
 
 static void u_xdl(const userinput * const u) {
-   char *tempstr,*tempstr2,*tempstr3;
+   char *tempstr,*tempstr2,*tempstr3, *cptr, *nptr;
    const char *spaces[] = { ""," ","  ","   ","    ","     ","      " };
-   int a,i,p,m,m1,s;
+   int a,i,p,m,m1,s,spaceleft,x;
    
    updatecontext(__FILE__,__FUNCTION__,__LINE__);
    
@@ -416,6 +421,136 @@
    tempstr2 = mycalloc(maxtextlength,"u_xdl");
    tempstr3 = mycalloc(maxtextlengthshort,"u_xdl");
 
+   if (u->method==method_xdl_channel_cust)
+     {
+       /* We are in a loop to display the formated stuff from the advert definition string */
+       for (a=0;a<MAXADVERTS && gdata.advert[a]!=NULL;a++)
+	 {
+	   memset(tempstr,0,maxtextlength);
+	   i=0;
+	   cptr=gdata.advert[a];
+	   nptr=tempstr;
+	   /* All strings will be null terminated.
+	      We must ensure we do no outstretch ourselves and write more than maxtextlength
+	      to the tempstring
+	   */
+	   spaceleft=maxtextlength-2;
+	   while (spaceleft>0)
+	     switch (*cptr)
+	       {
+	       case 0:
+		 spaceleft=0;
+		 break;
+	       case '%':
+		 cptr++;tempstr2[0]=0;
+		 switch(capchar(*(cptr++)))
+		   {
+		   case 'A': /* Number of slots in use */
+		     isnprintf(tempstr2, maxtextlength-1, "%i", gdata.slotsfull);
+		     break;
+		   case 'B': /* Totle slots */
+		     isnprintf(tempstr2, maxtextlength-1, "%i", gdata.slotsmax);
+		     break;
+		   case 'C': /* Number in queue */
+		     isnprintf(tempstr2, maxtextlength-1, "%i", gdata.inqueue);		     
+		     break;
+		   case 'D': /* Size of queue */
+		     isnprintf(tempstr2, maxtextlength-1, "%i", gdata.queuesize);
+		     break;
+		   case 'E': /* number in packs queue */
+		     isnprintf(tempstr2, maxtextlength-1, "%i", gdata.inslotsmaxqueue);
+		     break;
+		   case 'F': /* size of pack queue */
+		     isnprintf(tempstr2, maxtextlength-1, "%i", gdata.slotsmaxqueue);
+		     break;
+		   case 'G': /* pack speed record */
+		     isnprintf(tempstr2,maxtextlength-1, "%1.1fK/s", gdata.record);
+		     break;
+		   case 'H': /* number of lines in send to server queue*/
+		     {
+		       int srvq;
+		       for (srvq=0; gdata.serverq[srvq] && srvq<MAXSENDQ; srvq++);
+		       isnprintf(tempstr2, maxtextlength-1, "%i", srvq);
+		     }
+		     break;
+		   case 'I': /* ammount of data send to network in last 120 seconds*/
+		     {
+		       int count=0;
+		       for (i=0; i<120; i++)
+			 count += gdata.xdccsent[i];
+		       isnprintf(tempstr2, maxtextlength-1, "%i", count/1024);
+		     }
+		     break;
+		   case 'J': /* Average bandwidth in last 120 seconds */
+		     {
+		       int count=0;
+		       for (i=0; i<120; i++)
+			 count += gdata.xdccsent[i];
+		       isnprintf(tempstr2, maxtextlength-1, "%1.1fK/s", ((float)count)/120.0/1024.0);
+		     }
+		     break;
+		   case 'K': /* record average bandwidth */
+		     isnprintf(tempstr2,maxtextlength-1, "%1.1fK/s", gdata.sentrecord);
+		     break;
+		   case 'L': /* minimum required bandwidth */
+		     isnprintf(tempstr2,maxtextlength,"%1.1fK/s",gdata.overallminspeed);
+		     break;
+		   case 'W': /* packs offered */
+		     isnprintf(tempstr2,maxtextlength,"%i",gdata.numpacks);
+		     break;
+		   case 'X': /* total size of packs offered */
+		     {
+		       float ocount = 0;
+		       for (i=0; i<MAXXDCCS; i++)
+			 if (gdata.xdccs[i])
+			   ocount += (float)gdata.xdccs[i]->size;
+		       isnprintf(tempstr2,maxtextlength-1,"%1.1f MB",ocount/1024.0/1024.0);
+		     }
+		     break;
+		   case 'Y': /* total completed transfers */
+		     {
+		       int gcount=0;
+		       for (i=0; i<MAXXDCCS; i++)
+			 if (gdata.xdccs[i])
+			   gcount += gdata.xdccs[i]->gets;
+		       isnprintf(tempstr2, maxtextlength-1,"%i",gcount);
+		     }
+		     break;
+		   case 'Z': /* total transfered MB*/
+		     {
+		       char postfix;
+		       float totsent=getEngineerval(gdata.totalsent/1024.0/1024.0,
+						    "MGT\0",
+						    &postfix);
+		       
+		       isnprintf(tempstr2,maxtextlength-1,"%1.2f %cB",totsent,postfix);
+		     }
+		     break;
+		   default:
+		     cptr--;
+		   case '%':
+		     tempstr2[0]='%';
+		     tempstr2[1]=0;
+		     break;
+		   }
+		 isnprintf(nptr,spaceleft,"%s",tempstr2);
+		 spaceleft-=x=strlen(tempstr2);
+		 nptr+=x;
+		 break;		 
+	       default:
+		 spaceleft--;
+		 *(nptr++)=*(cptr++);
+	       }
+	   /*	   if (tempstr[0]!=0)*/
+	     u_respond(u,tempstr);
+	 }
+      mydelete(tempstr);
+      mydelete(tempstr2);
+      mydelete(tempstr3);
+      return;
+     }
+   
+
    if (u->method==method_xdl_channel_min) m = 1; else m = 0;
    if (u->method==method_xdl_channel_sum) m1 = 1; else m1 = 0;
    
@@ -1545,7 +1680,7 @@
    /* other variables */
    char *templine = mycalloc(maxtextlength,"u_rehash_templine");
    char *tempc = mycalloc(2,"u_rehash_tempc");
-   int h,i,j,k,found,filedescriptor,needtojump;
+   int h,i,j,k,found,filedescriptor=-1,needtojump;
    
    updatecontext(__FILE__,__FUNCTION__,__LINE__);
    
@@ -1558,10 +1693,14 @@
       mydelete(gdata.server[i]);
    for (i=0; i<MAXCHNLS; i++)
       gdata.t_channel[i] = gdata.r_channel[i] = NULL;
+   for (i=0; i<MAXADVERTS && gdata.advert[i]; i++)
+     {
+       mydelete (gdata.advert[i]);
+       gdata.advert[i]=NULL;
+     }
    
    gdata.r_overallminspeed = gdata.overallminspeed;
    gdata.r_transfermaxspeed = gdata.transfermaxspeed;
-   
    mydelete(gdata.logfile);
    gdata.logrotate = gdata.logstats = 0;
    mydelete(gdata.ignorefile);
@@ -1594,7 +1733,6 @@
    gdata.uploadallowed = gdata.uploadmaxsize = 0;
    mydelete(gdata.uploaddir);
    gdata.restrictlist = gdata.restrictsend = 0;
-   
    mydelete(gdata.loginname);
    set_loginname();
    
@@ -1631,7 +1769,7 @@
             }
          }
       }
-   
+   close(filedescriptor);
    /* see what needs to be redone */
    
    u_respond(u,"Reconfiguring...");
@@ -1857,7 +1995,9 @@
       if (gdata.channels[i]->plisttime) {
          isnprintf(tempstr2,maxtextlength-2,"%s, plist every %2i min (%s)",tempstr,
                   gdata.channels[i]->plisttime,
-                  gdata.channels[i]->flags & CHAN_MINIMAL ? "minimal" : (gdata.channels[i]->flags & CHAN_SUMMARY ? "summary" : "full"));
+                  gdata.channels[i]->flags & CHAN_MINIMAL ? "minimal" : 
+		   (gdata.channels[i]->flags & CHAN_SUMMARY ? "summary" : 
+		    (gdata.channels[i]->flags & CHAN_CUSTOM ? "custom" : "full")));
          strncpy(tempstr,tempstr2,maxtextlength-1);
          }
       
@@ -1974,9 +2114,42 @@
    mydelete(tempstr);
    }
 
+void ignoreuser(char* hostname, int bantime)
+{
+  /* Ban a host for bantime minutes */
+  int i, found;
+  if (!hostname)
+    return;
+  
+   for (found=i=0; (i<MAXIGNL && gdata.ignorelist[i] && !found); i++)
+      if (isbanned(i,hostname)) found++;
+   
+   if (i == MAXIGNL) {
+      outerror(1,"Out of ignore slots!, This shouldn't happen");
+      return;
+      }
+   if (!found) {
+
+      gdata.ignorelist[i] = mycalloc(sizeof(igninfo),"u_ignore_ignorelist[i]");
+      strncpy(gdata.ignorelist[i]->hostname,hostname,maxtextlength-1);
+      gdata.ignorelist[i]->flags &= ~IGN_FIRSTIGNORE;
+      gdata.ignorelist[i]->lastcontact = gdata.curtime;
+      }
+   else
+   	i--;
+      gdata.ignorelist[i]->flags |= IGN_IGNORING;   
+      gdata.ignorelist[i]->flags &= ~IGN_MANUAL & ~IGN_RANGE;
+   gdata.ignorelist[i]->bucket = (bantime*60)/IGN_TL;
+   ioutput(0,OUT_S|OUT_L|OUT_D,"0;33","IGNORE banned: %s (%i)",hostname,bantime);
+   write_ignorefile();
+}
+
+
+
 static void u_ignore(const userinput * const u) {
-   int i, num=0, found;
+   int i, num=0, found, mask;
    char *tempstr;
+   char* cptr;
    
    updatecontext(__FILE__,__FUNCTION__,__LINE__);
    
@@ -1986,14 +2159,16 @@
       u_respond(u,"Try specifying an amount of time to ignore");        
       return;
       }
-
-   if (!u->arg2 || strlen(u->arg2) < 4) {
+   cptr=u->arg2;
+   if (!cptr || strlen(cptr) < 4) {
       u_respond(u,"Try specifying a hostname longer than 4 characters");
       return;
       }
    
+   mask=(cptr[0]=='*')?IGN_RANGE:0;
+   
    for (found=i=0; (i<MAXIGNL && gdata.ignorelist[i] && !found); i++)
-      if (!strcmp(gdata.ignorelist[i]->hostname,u->arg2)) found++;
+     if (!strcmp(gdata.ignorelist[i]->hostname,cptr)) found++;
    
    if (i == MAXIGNL) {
       outerror(1,"Out of ignore slots!, This shouldn't happen");
@@ -2005,7 +2180,7 @@
    
    if (!found) {
       gdata.ignorelist[i] = mycalloc(sizeof(igninfo),"u_ignore_ignorelist[i]");
-      strncpy(gdata.ignorelist[i]->hostname,u->arg2,maxtextlength-1);
+      strncpy(gdata.ignorelist[i]->hostname,cptr,maxtextlength-1);
       gdata.ignorelist[i]->flags |= IGN_IGNORING;
       gdata.ignorelist[i]->flags &= ~IGN_FIRSTIGNORE;
       gdata.ignorelist[i]->lastcontact = gdata.curtime;
@@ -2013,11 +2188,12 @@
    else
       i--;
    gdata.ignorelist[i]->flags |= IGN_MANUAL;
+   gdata.ignorelist[i]->flags |= mask;
    gdata.ignorelist[i]->bucket = (num*60)/IGN_TL;
    
    isnprintf(tempstr,maxtextlength-2,
             "Ignore activated for *!*@%s which will last %i min",
-            u->arg2,num);
+            cptr,num);
    u_respond(u,tempstr);
    write_ignorefile();
 
@@ -2056,22 +2232,141 @@
    
    mydelete(tempstr);
    
+}
+
+static void u_humiliate (const userinput * const u)
+{
+  if (gdata.humiliate)
+    {
+      mydelete (gdata.humiliate);
+      gdata.humiliate=NULL;
+    }
+  if ((u->arg1) || (strlen(u->arg1e)>1))
+    {
+      strncpy(gdata.humiliate=mycalloc(maxtextlength,"u_humiliate"),
+	      u->arg1e, maxtextlength-2);
+    }
+}
+
+static void u_spdwrn(const userinput * const u)
+{
+  char *x=u->arg1;
+  updatecontext(__FILE__,__FUNCTION__,__LINE__);
+  if ((!x) || (strlen(x)!=1))
+    x="\0";
+  switch (x[0])
+    {
+    case '-':
+      gdata.nospeedwarnings=1;
+      u_respond(u,"*** SPDWRN will not warn users about bandwidth limits");
+     break;
+    case '+':
+      gdata.nospeedwarnings=0;
+      u_respond(u,"*** SPDWRN will warn users about bandwidth limits");
+      break;
+    default:
+      {
+	char temp[maxtextlength];
+	char* t=&(temp[0]);
+	isnprintf(t,maxtextlength-2,
+		  "Speed warning notices are %s. Use - to turn off, + to turn on",(gdata.nospeedwarnings)?"disabled":"enabled");
+	u_respond(u,t);
+
+      }
    }
+}
+
+
+static void u_public(const userinput * const u)
+{
+  char *x=u->arg1;
+  updatecontext(__FILE__,__FUNCTION__,__LINE__);
+  if ((!x) || (strlen(x)!=1))
+    x="\0";
+  switch (x[0])
+    {
+    case '-':
+      gdata.publictriggers=0;
+      u_respond(u,"*** PUBLIC will not respond to public triggers");
+     break;
+    case '+':
+      gdata.publictriggers=1;
+      u_respond(u,"*** PUBLIC public triggers will receive a response");
+      break;
+    default:
+      {
+        char temp[maxtextlength];
+        char* t=&(temp[0]);
+        isnprintf(t,maxtextlength-2,
+                  "Response to public triggers is %s. Use - to turn off, + to tu
+rn on",(gdata.publictriggers)?"on":"off");
+     u_respond(u,t);
 
+      }
 
+    }
+}
 static void u_nolist(const userinput * const u) {
-   int num = 0;
-   char *tempstr = mycalloc(maxtextlength,"u_nolist");
+   int num = 0, num2=-1, x=maxtextlength-2,y;
+   int on=0;
+   char tempstr[maxtextlength];
+   char *tstr=tempstr;
+   tempstr[0]=0;
    
    updatecontext(__FILE__,__FUNCTION__,__LINE__);
    
-   if (u->arg1) num = atoi(u->arg1);
-   gdata.nolisting=gdata.curtime + 60*num - 1;
-   isnprintf(tempstr,maxtextlength-2,
-   "*** XDCC List and PLIST have been disabled for the next %i minute%s",num,num!=1?"s":"");
+   /* Can we assume that -1 is 1111 1111 1111 1111 1111 1111 1111 1111
+      on a 32 bit architechture using 2s-compliment???
+      If so then surely -1>>1 represents the biggest positive number
+      representable?
+      I certainly hope so, as it's important here :)
+   */
+
+   if (u->arg1){
+     if (!strcasecmp(u->arg1,"on"))
+       {
+	 gdata.nolisting=(-3ul)>>1;
+	 num=-1;
+	 on=1;
+       }
+     else
+       gdata.nolisting=gdata.curtime + 60*(num=atoi(u->arg1));
+
+     if (u->arg2)
+       num2=(strcasecmp(u->arg2,"-q")==0)?0:atoi(u->arg2);
+   }
+   gdata.nolistbantime=num2;
+
+
+
+   if (num==0)
+     isnprintf(tstr,x,
+	       "*** XDCC List and PLIST have been enabled");
+   else
+     {
+       x-=y=isnprintf(tstr,x,
+		      "*** XDCC List and PLIST have been disabled%s",
+		      ((num2==-1)?"":" silently")
+		      );
+       tstr+=y;
+
+       if (!on)
+	 {
+	   x-=y=isnprintf(tstr,x," for the next %i minute%s",num,num!=1?"s":"");
+	   tstr+=y;
+	 }
+
+       if (num2>0)
+	 {
+	   x-=y=isnprintf(tstr,x," and any user requesting a list will be banned for %i minute%s",
+			  num2,num2!=1?"s":"");
+	   tstr+=y;
+	 }
+     }
+   
+
    u_respond(u,tempstr);
    
-   mydelete(tempstr);
    
    }
 
diff -BNru iroffer1.2b13/src/defines.h iroffer1.2b13+cpitchfor7/src/defines.h
--- iroffer1.2b13/src/defines.h	Sat Nov 10 17:06:40 2001
+++ iroffer1.2b13+cpitchfor7/src/defines.h	Tue Feb 12 23:15:43 2002
@@ -17,9 +17,9 @@
 #if !defined _IROFFER_DEFINES
 #define _IROFFER_DEFINES
 
-#define  VERSION "1.2b13"
-#define  VERSIONDATE "November 10th, 2001"
-#define  VERSIONDATEUTC 1005405514 /* "date +%s" */
+#define  VERSION "1.2b13+cpitchfor7"
+#define  VERSIONDATE "February 12th, 2002"
+#define  VERSIONDATEUTC 1013555332 /* "date +%s" */
 #define  RELEASE 1
 
 
@@ -98,7 +98,7 @@
 #define  SRVRTOUT  240
 
 /*       max number of people to keep track of in ignore list */
-#define  MAXIGNL  80
+#define  MAXIGNL  500
 /*       tollerance for ignore, seconds/request to decrement bucket */
 #define  IGN_TL    10
 /*       threshhold for ignore, number of requests in bucket */
@@ -141,11 +141,16 @@
 #define IGN_MANUAL      1
 #define IGN_IGNORING    2
 #define IGN_FIRSTIGNORE 4
+#define IGN_RANGE       8
 
 /* type definitions for channel_t flags */
 #define CHAN_ONCHAN     1
 #define CHAN_MINIMAL    2
 #define CHAN_SUMMARY    4
+#define CHAN_CUSTOM     8
+
+/* Maximum number of advert lines */
+#define MAXADVERTS      20
 
 /* type definistions: Screen, Log, DCC CHAT */
 #define OUT_S    1
diff -BNru iroffer1.2b13/src/globals.h iroffer1.2b13+cpitchfor7/src/globals.h
--- iroffer1.2b13/src/globals.h	Sat Nov 10 17:06:40 2001
+++ iroffer1.2b13+cpitchfor7/src/globals.h	Tue Feb 12 23:15:43 2002
@@ -150,7 +150,18 @@
 upload *uploads[MAXUPLDS];
 
 meminfo_t meminfo[MAXMEMINFO];
+  /* The custom advert */
+  char* advert[MAXADVERTS];
 
+  /* Time to ban a user
+     -1: Disable, normal list operation response
+      0: Ignore all list requests silently
+    n>0: Ban a user for n minutes should they xdcc list this bot
+  */
+  int nolistbantime;
+  int publictriggers;
+  char* humiliate;
+  int nospeedwarnings;
 } gdata_t;
 
 
diff -BNru iroffer1.2b13/src/headers.h iroffer1.2b13+cpitchfor7/src/headers.h
--- iroffer1.2b13/src/headers.h	Sat Nov 10 17:06:40 2001
+++ iroffer1.2b13+cpitchfor7/src/headers.h	Tue Feb 12 23:15:43 2002
@@ -162,7 +162,8 @@
    method_out_all         = 0x20,
    method_xdl_channel_min = 0x40,
    method_xdl_channel_sum = 0x80,
-   method_allow_all       = 0xFF
+   method_xdl_channel_cust= 0x100,
+   method_allow_all       = 0x1FF
    } userinput_method_e;
 
 typedef struct {
@@ -255,6 +256,7 @@
 unsigned long atoul (const char *str);
 unsigned long long atoull (const char *str);
 void ioutput(int beg, int dest, const char *color, const char *format, ...);
+void allchanmsg(const char *message);
 void privmsg(const char *nick, const char *format, ...);
 void notice(const char *nick, const char *format, ...);
 char* hostmasktoregex(char *str);
@@ -287,6 +289,8 @@
 int mysnprintf(char *str, size_t n, const char *format, ... );
 int myvsnprintf(char *str, size_t n, const char *format, va_list ap );
 #endif
+char capchar(const char c);
+float getEngineerval(const float value, const char *engfix, char *res);
 
 /* misc.cpp */
 void getconfig (void);
@@ -316,6 +320,7 @@
 char* getstatusline(char *str);
 char* getstatuslinenums(char *str);
 void sendxdlqueue(void);
+int addressedtome(const char *dest);
 int isthisforme (const char *dest, char *msg1);
 void initvars(void);
 void startupiroffer(void);
@@ -327,6 +332,7 @@
 void notifybandwidthtrans(void);
 void write_ignorefile(void);
 void read_ignorefile(void);
+int isbanned(const int i, const char* host);
 
 /* dccchat.cpp */
 int setupdccchatout(const char *nick);
@@ -373,6 +379,7 @@
 void u_fillwith_clean(userinput * const u);
 
 void u_parseit(userinput * const u);
+void ignoreuser(char* hostname, int bantime);
 
 #endif
 
diff -BNru iroffer1.2b13/src/iroffer.c iroffer1.2b13+cpitchfor7/src/iroffer.c
--- iroffer1.2b13/src/iroffer.c	Sat Nov 10 17:06:40 2001
+++ iroffer1.2b13+cpitchfor7/src/iroffer.c	Tue Feb 12 23:15:43 2002
@@ -630,11 +630,21 @@
       /*----- plist stuff ----- */
       if (gdata.serverstatus == 'C' && changemin && gdata.numpacks) {
          if (!gdata.queuesize || gdata.inqueue < gdata.queuesize) {
-            char *tchanf = NULL, *tchanm = NULL, *tchans = NULL;
+            char *tchanf = NULL, *tchanm = NULL, *tchans = NULL, *tchanc = NULL;
             
             for (i=0; gdata.channels[i] && i<MAXCHNLS; i++)
                if (gdata.channels[i]->plisttime && !((gdata.curtime/60)%(gdata.channels[i]->plisttime))) {
-                  if (gdata.channels[i]->flags & CHAN_MINIMAL) {
+                 if (gdata.channels[i]->flags & CHAN_CUSTOM) {
+		   if (tchanc) {
+		     strncat(tchanc,",",maxtextlength-strlen(tchanc)-1);
+		     strncat(tchanc,gdata.channels[i]->name,maxtextlength-strlen(tchanc)-1);
+		   }
+		   else {
+		     tchanc = mycalloc(maxtextlength,"mainloop_pubplist1m");
+		     strncpy(tchanc,gdata.channels[i]->name,maxtextlength-1);
+		   }
+		 }
+		 else if (gdata.channels[i]->flags & CHAN_MINIMAL) {
                      if (tchanm) {
                         strncat(tchanm,",",maxtextlength-strlen(tchanm)-1);
                         strncat(tchanm,gdata.channels[i]->name,maxtextlength-strlen(tchanm)-1);
@@ -693,7 +703,15 @@
                mydelete(pubplist);
                mydelete(tchanm);
                }
-            
+            if (tchanc) {
+               ioutput(0,OUT_S|OUT_D,NULL,"Plist sent to %s (custom)",tchanc);
+               pubplist = mycalloc(sizeof(userinput),"mainloop_pubplist2m");
+               u_fillwith_msg(pubplist,tchanc,"A A A A A xdl");
+               pubplist->method = method_xdl_channel_cust;
+               u_parseit(pubplist);
+               mydelete(pubplist);
+               mydelete(tchanc);
+               }
             }
          else
             ioutput(0,OUT_S|OUT_D,NULL,"Plist skipped, we seem to be rather busy");
@@ -1192,7 +1210,7 @@
       /* add/increment ignore list */
       j=0;
       for (i=0; i<MAXIGNL && gdata.ignorelist[i]; i++)
-         if (!strcmp(gdata.ignorelist[i]->hostname,hostname)) {
+         if (isbanned(i,hostname)) {
             /* already in list */
             j=1;
             gdata.ignorelist[i]->bucket++;
@@ -1219,14 +1237,14 @@
             gdata.ignorelist[i] = mycalloc(sizeof(igninfo),"privmsgparse_gdata.ignorelist[i]");
          strncpy(gdata.ignorelist[i]->hostname,hostname,maxtextlength-1);
          gdata.ignorelist[i]->bucket = 1;
-         gdata.ignorelist[i]->flags &= ~IGN_MANUAL & ~IGN_IGNORING & ~IGN_FIRSTIGNORE;
+         gdata.ignorelist[i]->flags &= ~IGN_RANGE & ~IGN_MANUAL & ~IGN_IGNORING & ~IGN_FIRSTIGNORE;
          gdata.ignorelist[i]->lastcontact = gdata.curtime;
          
          }
    
       /* see if we are ignoreing this person */
       for (i=0; i<MAXIGNL && gdata.ignorelist[i]; i++)
-         if (!strcmp(gdata.ignorelist[i]->hostname,hostname) && (gdata.ignorelist[i]->flags & IGN_IGNORING)) {
+         if (isbanned(i,hostname) && (gdata.ignorelist[i]->flags & IGN_IGNORING)) {
             if (gdata.ignorelist[i]->flags & IGN_FIRSTIGNORE) {
                 privmsg(nick,"Auto-ignore activated, ignoring *!*@%s until you calm down",hostname);
                 gdata.ignorelist[i]->flags &= ~IGN_FIRSTIGNORE;
@@ -1237,6 +1255,9 @@
 	    goto privmsgparse_cleanup; /* it's useful damnit! */
             }
       }
+   if (!gdata.publictriggers && !addressedtome(dest))
+     goto privmsgparse_cleanup;
+   
    
    /*----- CLIENTINFO ----- */
    if ( !gdata.ignore && (!strcmp(msg1,"\1CLIENTINFO")
@@ -1418,14 +1439,65 @@
    
    /*----- XDCC ----- */
    else if ( !gdata.ignore && (!strcmp(caps(msg1),"XDCC") || !strcmp(msg1,"\1XDCC") || !strcmp(caps(msg1),"CDCC") || !strcmp(msg1,"\1CDCC") )) {
-      gdata.inamnt[gdata.curtime%10]++;
       
+	 gdata.inamnt[gdata.curtime%10]++;
       caps(msg2);
       
       if (msg3 && msg3[strlen(msg3)-1] == '\1')
          msg3[strlen(msg3)-1] = '\0';
       
-      if ( msg2 && ( !strcmp(msg2,"LIST") || !strcmp(msg2,"LIST\1"))) {
+	 if ( msg2 && ( !strcmp(msg2,"LIST") || !strcmp(msg2,"LIST\1")))
+	   {
+	     if ((gdata.nolisting > gdata.curtime) && (gdata.nolistbantime!=-1))
+	       {
+		 if (gdata.nolistbantime>0)
+		   {
+		     /* We have someone to ban!! hurrah! */
+		     ignoreuser(hostname, gdata.nolistbantime);
+		     ioutput(0,OUT_S|OUT_L|OUT_D,"0;33","XDCC LIST banned: %s (%s)",nick,hostmask);
+
+		     if (gdata.humiliate)
+		       {
+			 char tempmessage[maxtextlength];
+			 char* cptr=gdata.humiliate;
+			 char* tptr=&(tempmessage[0]);
+			 int z,a;
+			 tempmessage[0]=tempmessage[maxtextlength-1]=0;
+			 for (z=maxtextlength-2;z>0 && *cptr!=0;z--)
+			   if (*cptr=='%')
+			     switch (*(cptr+1))
+			       {
+			       case 'U':
+			       case 'u':
+				 cptr+=2;
+				 strncpy(tptr,nick,z);
+				 a=strlen(tptr);
+				 tptr+=a;
+				 z-=a-1;
+				 break;
+			       case 'T':
+			       case 't':
+				 cptr+=2;
+				 a=isnprintf(tptr, z, "%i minute%s",
+					     gdata.nolistbantime,
+					     (gdata.nolistbantime==1)?"":"s"
+					     );
+				 tptr+=a;
+				 z-=a-1;
+			       }		       
+			   else
+			     *(tptr++)=*(cptr++);
+			 *tptr=0; 
+			 ioutput(0,OUT_S|OUT_L|OUT_D,"0;33",
+				 "XDCC BANSEND to %s: %s",
+				 nick,tempmessage);		
+			 allchanmsg(tempmessage);
+		       }
+		     
+		   }
+	       }
+	     else
+	       {
          if (!gdata.attop) gototop();
          
 	 if (gdata.restrictlist && !isinmemberlist(nick))
@@ -1456,7 +1528,7 @@
          ioutput(0,OUT_S|OUT_L|OUT_D,"0;33","XDCC LIST %s: (%s)",(j==1?"ignored":(j==2?"denied":"queued")),hostmask);
          
          }
-      else if(!strcmp(gdata.caps_nick,dest))
+	   } else if(!strcmp(gdata.caps_nick,dest))
 	{
          if ( msg2 && msg3 && (!strcmp(msg2,"SEND") || !strcmp(msg2,"GET"))) {
          if (!gdata.attop) gototop();
diff -BNru iroffer1.2b13/src/misc.c iroffer1.2b13+cpitchfor7/src/misc.c
--- iroffer1.2b13/src/misc.c	Sat Nov 10 17:06:40 2001
+++ iroffer1.2b13+cpitchfor7/src/misc.c	Tue Feb 12 23:15:43 2002
@@ -23,7 +23,7 @@
 void getconfig (void) {
    char *templine = mycalloc(maxtextlength,"getconfig_templine");
    char *tempc = mycalloc(2,"getconfig_tempc");
-   int h,i,filedescriptor;
+   int h,i,filedescriptor=-1;
    
    updatecontext(__FILE__,__FUNCTION__,__LINE__);
 
@@ -53,7 +53,7 @@
             }
           }
        }
-   
+   close(filedescriptor);   
    printf("*** Checking for completeness of config file ...\n");
    
    if ( gdata.server[0] == NULL
@@ -103,7 +103,8 @@
       type[i] = line[i];
       }
    type[i] = '\0';
-   
+   if (line[i]==0)
+     i--;
    for (j=i+1; j<maxtextlength; j++) {
       if (line[j] == '\0')
          break;
@@ -163,6 +164,37 @@
       for (i=0; gdata.server[i] && i<MAXSRVS; i++) ;
       gdata.server[i] = var;
       }
+   else if ( ! strcmp(type,"advert")) {
+     for (i=0; i<MAXADVERTS && gdata.advert[i]!=NULL;i++);
+     if (gdata.advert[i]==NULL)
+       gdata.advert[i]=var;
+   }
+   else if ( ! strcmp(type,"nolist")) {
+     char* cptr;
+     gdata.nolisting=(-3ul)>>1;
+     if ((cptr=getpart(var,1,"getconfig_set_nolist")))
+	 gdata.nolistbantime=(!strcasecmp(cptr,"-q"))?0:atoi(cptr);
+     else
+       gdata.nolistbantime=-1;
+     mydelete (cptr);
+   }
+   else if ( ! strcmp(type,"public")) {
+     gdata.publictriggers=1;
+   }
+   else if ( ! strcmp(type,"speedwarnings")) {
+     gdata.nospeedwarnings=0;
+   }
+   else if ( ! strcmp(type,"nospeedwarnings")) {
+     gdata.nospeedwarnings=10;
+   }
+   else if ( ! strcmp(type,"nopublic")) {
+     gdata.publictriggers=0;
+   }
+   else if ( ! strcmp(type,"humiliate")) {
+     if (gdata.humiliate)
+       mydelete(gdata.humiliate);
+     gdata.humiliate=var;
+   }
    else if ( ! strcmp(type,"channel")) {
       char *tptr = NULL, *tptr2 = NULL, *tname;
       int ok=1;
@@ -206,6 +238,11 @@
                strncpy(cptr->key,tptr2,maxtextlengthshort-1);
             else ok=0;
             }
+	 else if ((!strcmp(tptr,"-advert")) && (cptr->flags | CHAN_CUSTOM))
+	   {
+	     i++;
+	     cptr->flags |= CHAN_CUSTOM;
+	   }
          else ok=0;
          
          mydelete(tptr);
@@ -1611,6 +1648,12 @@
    mydelete(tempstr);
    }
 
+int addressedtome(const char *dest)
+{
+     if (!dest) { outerror(1,"addressedtome() got NULL value"); return 1; }
+     return (!strcmp(gdata.caps_nick,dest));
+}
+
 int isthisforme (const char *dest, char *msg1) {
    if (!msg1 || !dest) { outerror(1,"isthisforme() got NULL value"); return 1; }
    
@@ -1632,6 +1675,7 @@
    }
 
 void initvars(void) {
+  int i;
   
    bzero((char *) gdata.serverq, MAXSENDQ * sizeof(char*) );
    bzero((char *) gdata.inamnt, 10 * sizeof(int) );
@@ -1693,7 +1737,12 @@
    gdata.restrictlist = gdata.restrictsend = 0;
    
    gdata.startuptime = gdata.curtime = time(NULL);
-   
+   for (i=0;i<MAXADVERTS;i++)
+     gdata.advert[i]=NULL;
+   gdata.nolistbantime=-1;
+   gdata.publictriggers=1;
+   gdata.humiliate=NULL;
+   gdata.nospeedwarnings=0;
    }
    
 void startupiroffer(void) {
@@ -2016,7 +2065,7 @@
    updatecontext(__FILE__,__FUNCTION__,__LINE__);
 
    if (gdata.exiting) return;
-   if (!gdata.maxb) return;
+   if (!gdata.maxb || gdata.nospeedwarnings) return;
    
    
    j = 0;
@@ -2046,7 +2095,7 @@
    
    updatecontext(__FILE__,__FUNCTION__,__LINE__);
 
-   if (gdata.exiting) return;
+   if (gdata.exiting || gdata.nospeedwarnings) return;
    
    for (i=0; i<MAXTRANS; i++)
       if (gdata.trans[i] != NULL
@@ -2140,6 +2189,32 @@
    ioutput(3,OUT_S|OUT_D,NULL,"Done");
    }
 
+
+
+int isbanned(const int i, const char* host)
+{
+  /* This function check to see if the host is in the list either
+     directly or via a netmask */
+  int x,y;
+  char *hptr;
+
+  if (!gdata.ignorelist[i] || !host)
+    return 0;
+  hptr=gdata.ignorelist[i]->hostname;
+  if (gdata.ignorelist[i]->flags & IGN_RANGE)
+    {
+      /* Its a range so we have to check the host name matches */
+      x=strlen(++hptr);
+      y=strlen(host);
+      if (y<x)
+	return 0;
+      return (!strcmp(&(host[y-x]),hptr))?1:0;
+    }
+  return (!strcmp(hptr,host));
+}
+  
+      
+	  
 
 /* End of File */
 
diff -BNru iroffer1.2b13/src/utilities.c iroffer1.2b13+cpitchfor7/src/utilities.c
--- iroffer1.2b13/src/utilities.c	Sat Nov 10 17:06:40 2001
+++ iroffer1.2b13+cpitchfor7/src/utilities.c	Tue Feb 12 23:15:43 2002
@@ -124,6 +124,11 @@
    return part;
    }
 
+char capchar(const char c)
+{
+  return (c>='a' && c<='z')?(c-32):c;
+}
+
 char* caps(char *text) {
    int i;
    if (text)
@@ -198,6 +203,20 @@
    return highest;
    }
 
+float getEngineerval(const float value, const char *engfix, char *res)
+{
+  float fval=value;
+  int x,y;
+  if ((engfix==NULL) || (y=strlen(engfix)<1) || (res==NULL))
+    return 0;
+  y--;
+  for (x=0;x<y && fval>1024;x++, fval/=1024.0);
+  *res=engfix[x];
+  return fval;
+}
+
+
+
 void getos (void) {
 
    struct utsname u1;
@@ -591,6 +610,20 @@
       }
    
    }
+
+void allchanmsg(const char *message)
+{
+  int i;
+  char temp[maxtextlength];
+  temp[0]=0;
+  for (i=0; gdata.channels[i] && i<MAXCHNLS; i++)
+    {
+      if (temp[0]!=0)
+	strncat(temp,",",maxtextlength-strlen(temp)-1);
+      strncat(temp,gdata.channels[i]->name,maxtextlength-strlen(temp)-1);
+    }
+  privmsg (temp, "%s", message);
+}
 
 void privmsg(const char *nick, const char *format, ...) {
    char tempstr[maxtextlength];
