
+ = Added a feature
- = Fixed a bug
* = Changed something
^ = Other

Sun 05-26-02
- Fixed command parser checking wrong flags
- Fixed permissions being set incorrect on pid file

Sun 05-05-02
- Fixed kick detection code being broken
- Fixed logging not working in some cases
- Kludge for DCC send problem
- Fixed "ON" not being recognized in SET command
- Fixed garbage pointers being added to list if conn::conn()
   failed
- Worked around a possible GCC bug involving templates
   and our list iterator (?????)
^ Stress tested: no more crashes.
^ Release 1.0-final

Mon 04-22-02
- Fixed crash if user was re-defined in config
+ contributed sample.conf merged. updated.

Sat 04-20-02
* Make sure NDEBUG is defined (to disable assert()) in non-debug
  builds
- Fixed a few problems w/ logfile send error handling
- Fixed potential collisions between enums in config.h and config.cpp

Mon 04-15-02
+ Merge the interval timer class code that i wrote some time ago.
    + new types: timer, generic_timer
    + new files: timer.cc timer.h
* Switched conn linked list to list type
+ add list<conn> to server.cpp
* various changes to use new list system
* change server 30- and 60-sec timer to use new timer interface
* cleaned up the linked list code quite a bit
+ added modification count to linked list and iterator to check
  for concurrent modification. this is the biggest problem i see
  with the code right now, and i know of at least one instance
  where the list is modified under the iterator during traversal.
* removed prev() functionality from iterator. i don't use it,
  and it was crappily implemented anyway
* rename list::num() to size()
* changed idle-killer for DCCs: no longer do we go through the
  list every 90 seconds or whatever. Each dcc now creates a "ONE_SHOT"
  timer that will automatically destroy it in 90 seconds. Should
  the connection be accept()'ed, the timer will be de-activated
^ For DCC sends, i noticed that the last packets were being dropped
  at times. This started happening after we began ignoring the ACK
  packets. This happens because ezb closes the socket after everything
  has been sent, and the acks the peer tries to send result
  in a ECONNRESET or something like that, and it stops read()'ing.
* So my half-assed solution is to ignore all events from the socket
  once the file has been sent, and use a one-shot timer to destroy
  the DCC in 30 seconds.
^ Might want to consider one timer for all dccs ?


Fri 04-12-02
+ Merge latest SSL diff from HoE
- fixed no-snprintf() and no-vsnprintf() work-arounds being stupid
* disabled set_new_handler() call for now
- fixed config file fd not being closed

Sun 03-24-02
- Fix dynbuff::copy_line() not recognizing end of buffer
  (This fixes at least one crash)
+ Add assert() for null entry add to linkedlist.
^ Release pre10

Mon 03-18-02
+ Merge contributed getpwnam() lookup patch for mdidentd
- Fix "impossible" scenario not being handled in login procedure
- Fix a couple of bugs w/ logfile sending
* Disable dccsend/dccview commands

Tue 03-05-02
- Fixed bytes-to-server not being updated

Sat 03-02-02
+ Documentation updates
+ Add SSL cert file generation script by HoE
^ Release 1.0-pre9

Thursday 02-28-02
* Inline parts of the socket code
+ Add null pointer to check to port_in_set()

Monday 02-25-02
- Fixed a memory leak in BURC code stripper
- Fixed 100% cpu usage if doing local DCC proxy
- Fixed ssl-listen ports being activated if SSL system
  could not be initialized
+ Check for set_new_handler() before using it
* abolished dcc::dcc_info_t. We just need the sockets.
- Fixed IRC password not being parsed in conn command
* Increase bucket size of command parser hash table from 31 to 41

Sunday 02-24-02
- Fixed memory leak with log file names
+ Updated documentation

Saturday 02-23-02
- Fixed parsing of '\t' in config file.
+ re-introduce ruleset list field to conn
+ add several static functions to ruleset to accomodate
    list calling of:
        is_allowed
        is_allowed_to
        register_connection
        unregister_connection

  this simplifies the code in someplaces
+ rulesets work again; it wasn't a glorious re-write as I
   hoped for, any many things revert back to the old way.
   If it ain't broke, don't fix it.
^ released pre8

Friday 02-22-02
- Fixed the list iterator remove(), and ruleset == operator
  quirks -- I think. It needs to be tested.
- Fixed compile problem with G++ 3.0 (new(nothrow) needs std:: prefix)
+ implement a cheap failed operator new handler


Thu 02-21-02
* Removed pre and post-fix ++ operators from list_iterator
  class.
+ Added next(), prev(), has_next(), and has_prev() functions
  to list_iterator class.
* Converted all iterators to new style.
* Converted ruleset class to use new list members. Doesn't seem
  to work though.
+ Finished GCC 2.95.x workaround. Does it work? We'll see.

Wed 02-20-02
* Start adding work arounds for gcc 2.95.x bug
+ Add rs_host list named to_hosts and from_hosts to ruleset class.
  Remove the orignal "rs_hosts" list.

Sun 02-17-02
- Fixed client commands being ignored after reattach ?? (data was left
    in the buffer)
- Fixed compile problem with USE_SELECT

Sat 02-16-02
+ add sanity checks for SSL variables
+ further DCC code updates
* removed dynbuff.o dependancy in mdidentd code. it was only
  one instance, for check_real_user(), which was crap anyway.
  Other reason was that it would require SSL libs if SSL support
  was to be built
+ added checks for snprintf() and vsnprintf()
- fixed stupid crash on detach with db.zap() call messing with
  pointer to delete'd memory. added couple of stupid one-line fixes
  to compensate
^ release pre7

Fri 02-15-02
^ Discovered a crash in the DCC code. It's been there forever,
  in dccsock::event_handler(). It was unaware
  that it might be destroyed after calling owner->poll(),
  and was afterwards attempting to access delete'd memory.
* Abolished dcc_list_t
* removed conn::my_dccs member
* removed conn::do_dcc() -- code moved to dccsock::event_handler()
+ added static list<dcc> conn::dcc_list member
+ added owner field to all DCCs
+ added 'priv' system to DCCs, basically to replace the filename and
    'islog' field that the dcc_list_t crap stored.
- fixed conn::cprintf() bombing if client didn't exist


Thu 02-14-02
* Simplied dcc sending:
    * no longer waits for ack before sending next packet
    * only checks for POLLOUT and then sends the next packet
    * totally ignores anything sent by the receiver
    * removed 'pos' field
* The reason for this was to allow sending files as a DCC CHAT.
  This was necessary because:
+ Added LOG VIEW command (merging bits of patch from Roi Dayan)
  basically sends logfile over DCC CHAT. We are clever and share
  the code with LOG SEND. Also updated help entry for LOG command.
- Fixed many bad uses of list::get(i), switching to use of iterators
  and thereby improving performance
+ Added __DEBUG__ only DCCSEND and CHATSEND commands
+ merged SSL patch from Hoe (with a lot of work :)
* SSL Patch Change summary:
    + added --with-ssl argument to configure script
    + added new configuration variable, "cert-file" and new configuration
        command "listen-ssl"
    + added SSL compliant add()/write() member functions to dynbuff class
    + extended "CONN" command to have -ssl argument
    + extended do_connect() to have ssl argument
    + added "SSL * ssl" field to pollsocket objects
    + added several supporting functions to pollsocket class for SSL
    + added 'in_ssl' variable to conn class and supporting argument to
       its constructor
    + other things


Mon 02-11-02
- Merge some fixes I did remotely over the weekend:
    some fixes to POLLIN/POLLOUT regulation
* removed dynbuff::peek() and dynbuff::get()
- Fixed a possible problem with dynbuff::optimize()
  I think it was screwed entirely. Worse, its been like
  that forever. This was likely the cause of the weird heap corruption (????)
  i saw during heavy load toasting the other day.
+ add pollsocket::printf()
+ add pollsocket::printf_raw()
* both intended as replacements for fdprintf()
- removed SUPER_MY_STRDUP
* renamed my_strdup(const char *, int) to my_strndup(const char *, int)
* removed the ghetto password generator
* removed min/max-client/server-inputQ config variables
+ added, as a replacement, min-buffer-size and max-buffer-size
  config variables; also added checks in check_config() to guarantee
  sane values.
* switch to vsnprintf() for var-arg needs. it's safer, but i don't think it's
   standard, so i ought to add ./configure checks to it. I'll wait till
   people bitch about it.
^ pre6 released

Thu 02-07-02
+ Finally, added --enable-debug argument to ./configure script,
  which means I don't have to screw with the makefiles anymore

Tue 02-05-02
- fixed failed socket creation in ircproxy_listen() not
  being handled
+ add rate regulation to DCC pipe code
- fixed logfile::LOG_NONE not being recognized
- fixed handling of ezb command with no args. Was causing
  a crash w/ the new parser. Need to be make sure not to return
  0 from command handler if we are given null argument string.
- fixed 'quit' handler again; both for standard and ezb-command
  case

Monday 02-04-02
+ added some basic rate limiting so buffers don't blow up
- this fixes packet loss during high traffic
+ re-added min/max server/client input queue restrictions
* Remove gay ezbounce.c file from misc/ directory. Nobody cares

Friday 02-01-02
- fix ircaddr classes not handling broken NICK strings (in n!u@h format)

Sat 01-26-02
- fix a bug in the compress() algo.
+ add #include <sys/time.h>
- fix a crash on full socket table situation: conn destructor
    was trying to delete garbage pointers; now sets all elements
    to zero before any bail-out situations

Thu 01-24-02
- removed dynbuff::have_char() and dynbuff::get_pos()
* inlined some of the one-line dynbuff functions
+ added better document dynbuff code
+ new class: db_parser
    allows for much more efficient line by line parsing
    it gives direct pointers to the internal data rather
    than making copies,
+ added char * db_parser::get_next_line(bool) as the interface
+ added db_parser::zap() to shrink the buffer after getting done
  parsing it.
* dynbuff::get_line() renamed to 'copy_line' but disabled
    for now cause it sucks.
* cleaned up conn::parse() and conn::parse_incoming() a whole bunch
   thanks to new db_parser.
* conn::check_client() and conn::check_server() also cleaned up a bunch
^ if socket is marked readable, and FIONREAD says zero bytes, (and in return
   read() will yield 0) then socket has been closed.
* got rid of the socket list. we operate exclusively with a table now. also,
    clean up some debug messages in the file
+ added pollsocket::create_table() to facilitate run-time user configuration
  of socket table size.
* vastly simplified the pollsocket::compress() algorithm.
+ added config hooks for max_sockets configuration variable

Sat 01-19-02
^ some work on the socket code:
+ added two buffers per socket object
+ new socket functions:
    /* Flush input buffer ... */
    int flush(pollsocket *);             /* ... to another socket (output buff) */
    int flush(int, int);                 /* ... to a raw file descriptor */
    /* Flush output buffer ... */
    int flushO(pollsocket *);            /* ... to another socket (input buff) */
    int flushO(int = 0);                 /* ... out our own fd */

Sun 01-06-02
- Fixed /save clobbering password field on original userdef
^ release pre5

Sun 12-30-01
- Fixed compile error (on FreeBSD et al) with order of 
  #include <sys/socket.h> statement in dynbuff.cpp
+ Updated some documentation. I hate it.

Fri 12-21-01
- Fixed identd.cpp compile problem on some
  systems
^ pre4 out -- finally :-P

Tue 12-11-01
* Copied gettok(), safe_strcpy() and fdprintf() over to
  mdidentd source. No longer do we link with general.o,
  shaving several kilobytes off the executable.
+ 'reattach' command now reattaches to first (and only)
  session if there is only one session and the user does
  not supply a argument.
* Disable admin reattach-to-any-user functionality for now
- Tried to fix the compile problem on GCC 2.95.2 with typedef
  pointer to member function
* Rejoin channel when kicked (detached)

Fri 11-30-01
- Fixed stupid stray ';' in config.cpp after an
  if statement

Wed 11-28-01
* Further cleanups to dcc.cpp

Thursday 11-22-01
- Fix a compilation problem on CYGWIN (add #include
  <sys/socket.h> for dynbuff.cpp) -- too bad there is a
  gay GCC bug that prevents the rest of it from compiling...
  (same problem on Debian systems apparently)
* Cleaned up dcc code a bit -- added more checks for
   failed write() in attempt to track ever-elusive 100%
   CPU usage on FreeBSD problem. I think I've nailed it
   this time. Cleaned up the function a bit while I was at,
   mainly by adding a error: section and goto'ing there,
   rather than 5-6 seperate instances of the same 
   close_all(); return DCC_ERROR; code block.

Monday 11-19-01
- Fixed CTCP pings not being caught on detach.

Fri 11-16-01
- Fixed crash on 'LOG SEND' w/ no arguments.

Thu 11-15-01
+ There's nothing like updating documentation at 1:30 in the morning.
- Oops, new default option code wasn't letting u listen on ports
  besides 6667.
- Fixed config temp variables not being freed on parse error
   exit.

Wed 11-14-01
- Fixed default proxy options not being set
- Fixed mdidentd not closing its sockets (!!!!!!!!!!!!!!!)
- Fixed user config flags and such not being transferred
  to existing users after rehash (add user_options::copy_config_only
  to facilitiate this)
^ Another report of a 100% CPU usage problem. I have no
  idea what is causing it... Perhaps a quirk with not
  handling POLLERR/POLLHUP properly, but I checked, and
  it looks like they are... Made some minor changes, but
  I'm still confused.
+ Added a few defines to general.cpp .. to basically prevent
  some extra stuff from being compiled for mdidentd. Then I
  realized I didn't know how to get those defined during
  compilation... We need to either copy those 3 functions over
  to mdidentd, split up the general.cpp file, or rewrite mdidentd
  totally. I'm up for the latter. Just not now.
* Cleaned up conn::is_authorized() a bit -- removed the unnecessary
  call to getsockname(), for example.
* Changed do_rule_set() to use mk_ppchar() and friends -- this fixes
  a few possible bugs that I noticed


Tue 11-13-01
- Fixed vhost list not being destroyed on config file load
  failure
+ Added userdef::sync_lists() to handle integrating the new
  users into the old one after rehash
+ Added ruleset::sync_lists(), to do the same thing for rulesets
* Removed remains of reload_config_file()
+ Added __list_iter::attach(), to make it walk another list
- Fixed pcfg.configfile not being set
+ Added signal handler for SIGSEGV
*  ... actually, screw that, I won't use it for now, it won't dump
   core if I catch the signal. There's a way i'm sure..
+ Added a copy constructor for ircaddr -- it was kinda necessary --
  see incoming join handler
- Fixed garbage prefs field in new user_options  ??
^ I think we have a working rehash -- it needs some testing, but..
   at first glance, it works.
+ Added hooks for ABOUT and VERSION -- creeping featurism :-)
+ Added hook for a DEBUG command -- i think this will be useful. Just to
  dump the list of rulesets and what not. Of course normally it will be
  disabled.


Mon 11-12-01
- copy_fake_ident() should work again
- auto-server after login command works again
+ added show_whois(), so /whois on user id doesn't show entire
  list of users
+ Added handler for incoming PING, PONG, and ERROR, and moved the
  server ping handler to its new home.
* We now respond to all Server PINGs, even if we are not detached.
* Cleaned up cprintf() a bit -- still room for improvement though.
+ started writing ircproxy_do_rehash() -- i'm tired though;
  gonna finish  this up tomorrow.

Sun 11-11-01
* Clarify local_saddr and client_saddr:
    local_saddr = getsockname() i.e., the port and interface
                                      we accepted the connection on
    client_saddr = getpeername() i.e. the port and address the
                                       client is from.
+ Added light weight ircaddr_simple structure -- lightweight
  as in no memory allocations, useful within scope of function
  and not globally; difference is it sets ! and @ characters to
  null. so:
   __ircaddr is the base, ircaddr is the original derived class,
  and now ircaddr_simple
+ Added global option "listen-vhost"
+ Added user option "default-vhost"
* Removed '-c' command line option -- vhost setting is now done
  thru the above methods. -b command line option remains, and simply
  overwrites anything that might have been set w/ listen-vhost
+ Display a few user stats after printing "created user"
- Fixed trailing whitespace characters causing problems in configuration
  business. We now remove those before processing.
+ Add big command list for help.
* rename silly ezbounce_guy to EZBOUNCE_HEADER :-P
+ Finished 'trace' command
- Fixed nick_incoming handler setting nickname to original
- Fixed a couple of zombie issues. Checking !c->stat don't
  really work, cause something always gets left over
  in the stat field. So call c->dead().. and also,
  made trace handle zombies.
^ Hmm, what the heck? I thought I made a reload command.
  Apparently I didn't.
- Fixed crash in logging -- extra % chars in format string
  for one of the writes
+ Added hooks and trunk for reload command

Fri 11-09-01
- Fixed userdef::vhosts not being deleted
* Made sure everything is freed after proxy is terminated
  to keep the memory-leak detecting tools happy.
- Fixed unnecessary memory allocations for
  shitlist, vhosts, and users in main()
^ Yawn, there is a memory leak somewhere involving logfile::lock() and
  friends. Gotta track it down sometime. Overall, if this dmalloc tool
  is right, then I am impressed w/ my ability to write leak-free code ;-)
+ Added a remove() method to the list iterator, right now only used
  by strlist_remove(), but hey, it's a bit more efficient now,
  certainly not O(n^2)

Thu 11-08-01
+ Added some more flare to trace command.
- Fixed on_server_disconnect() not clearing GOTSERVINFO and
  friends -- this was causing old serverinfo variables and
  what not to be left over if we reconnected.
- Fixed __popt not being zeroed out after allocation --
   how did I miss this one? And most importantly, why did
   it never crash?
- Fixed __popt also not being de-allocated if parsing
   was succesful.
- Fixed __popt members not being de-allocated either.

Tue 11-06-01
+ Added gettok_ptr() -- returns pointer to n'th token
  and everything else following it; mainly to avoid an
  additional buffer for the standard gettok() call that
  we use in a few places that is unnecessary because we
  immediately duplicate that buffer.
^ checked RFC 1459 -- says IRC must use \r\n, and 512
  chars max per line. Ok. \r\n it is.
+ Added hooks for TOPIC and NOTICE and QUIT
* Cleaned up the incoming PRIVMSG handler a bit.
- Fixed a few cases of \n to \r\n -- lot more to do however
* Rewrote logfile::write() --  a lot nicer now
* Decided that the file-writing logic will stay in
  logfile::write() -- it won't do any parsing though, our
  command handlers will do that, and send the proper information
  to logfile::write() which is now in the form:
    int logfile::write(int flags, const ircaddr * source,
        const char * target, const char * text, const char * extra)
* Removed logfile::parse()
- Fixed QUITs not being logged - at all!! Oops!!
- Fixed NICK changes not being logged either, hmm
* All handlers except PRIVMSG now take care of the logging.
  Testing needed.
* Made no_leading() handle null strings
* logging now prints channel before nick.. i.e.
    [#blah] <joe> i suck
+ Wrote a very basic trace command .. we'll work on it later.

Mon 11-05-01
* Removed conn::rinfo structure
* Removed handlers, constants for reattach info gathering thing
* Removed reattach_complete()
* Removed reattach_cancel()
* Removed 'REATTACHING' state all together... changed the
  whole process; we will now keep track of nickname, and
  channels user is on actively.
- Fixed 003-005 Handlers -- some were copying wrong
  token, some weren't copying enough. Also, we get
  positive confirmation on name of server here...
+ Added conn::uinfo::channels -- simple list to hold
    channels
+ Added hooks for incoming KICK, JOIN, PART, and MODE
  -- we need these to keep track of the channels we're on,
  AND, i eventually plan to convert the logfile code to use
  these hooks instead of doing its own parsing.
- Fixed 005 being sent incorrectly -- was not putting nickname in
  there. AND it was being sent if it didn't even exist.
+ New files: ircaddr.cc and ircaddr.h -- for class ircaddr,
  which just takes a raw n!user@host address and splits it up
  into chunks. Just wanted to avoid duplication of parsing code
* Updated lib/ directory makefile to not use redundant -o
  compiler option
+ SUPER_MY_STRDUP has been activated!!!
+ Added ischan()
+ Add another no_leading(); this time char * instead of const char *,
   don't wanna deal with the w/ const / no const bs compiler
    messages anymore.
+ Changed the way IRC nickname, ident, and hostnames are stored. We now
   have a member, __uinfo::irc which is of type ircaddr that will do that.
+ Wrote handler for PART, removes channel parted from channels list
+ Improved linked list remove code, we were finding the node, and then
  calling then calling find_by_idx. Faster now.
+ Added __list_core::remove(node *) to facilitate this
+ Added typedef list<char> strlist ...
+ Added strlist_remove() function to remove a string -- the standard
   remove() won't work becuase it don't do string compares.
+ Added simple handler for KICK, again to remove that channel from the list
   when we're out.
^ Reattach works under the new system -- gonna call it a day


Sun 11-04-01
- Oops, calling clearf() instead of clearp() in 'set' command

Sun 10-28-01
+ Added some stuff to CHANGES file
+ Added calls to ircproxy_save_prefs() as we exit

Sat 10-27-01
+ Additional help text and documentation updates
- Fixed 'LOG SET' w/o args causing a crash ??
^ We are still getting weird random corruption. I was not
  able to login after 8 hours because password field had
  evidently changed. THis is the 3rd time that has happened,
  and we still have garbage in user-file issue.
^ Stress testing with 250 clones has revealed *serious* memory
  corruption
- Fixed possible cause of corruption -- Forgot a &, was calling
  copy constructor for user_options -- too bad i didn't define
  a copy constructor (not w/ a reference), so I dunno WTF was
  being called.. Probably a default one doing shallow copies of
  everything ?? Oh well, fixed, and massive clone floods have not
  crashed it yet.
^ Ok, new crash found. It occurs in pollsocket::compress(), it was
  discovered after another big ass clone flood. Wow, it's been there
  forever, but never hit, because the array would never get that big.
  But the clone flood revealed it. Array is shrunk, and out of bounds
  accesses occur.
- Ok, fixed now I think??
+ /set VHOST now works
^ Stress testing revealed another crash. It took about 1200 clients connecting
    at once, but we ended up with a corrupt conn object with several garbage
    fields. In this case, conn::log was corrupt, and we ended up with a 34 mb
    core dump. I think it's because we don't handle failed memory allocations.

Fri 10-26-01
* Changed cprintf_multiline() -- no longer need that silly
   \a stuff
+ Implemented help system. A few things left to be done there,
   but the core is done. Yay.
+ Updated Changes file.
- Fixed pcfg.logfile not being set (oops, accidental fall-thru when setting
   user file)

Thu 10-25-01
+ 'save' command now works for all users, but the default user; it will
   copy his prefs over to his userdef's prefs.
+ .. add user_options::copy() to facilitate this (essentially copy
   constructor)
+ Improve 'allowed' so that it will lookup for different user if requested
* Renamed conn::find_by_id() to conn::lookup()
* Renamed userdef::save_options() to ircproxy_save_prefs() and
   ircproxy_load_prefs()
- Fix user_options::load() loading to flags :-P
+ `autopass' and 'fake-ident' are now properly saved
- Fix improper calls to user_options::get() to check preferences
   in 'set' command -- use checkp()
* Make config.cpp calls to user_options::setf/clearf also do setp && clearp
- Fixed another incorrect use of user_options::get() on prefs variable
* Eliminate unnecessary `user_options * conn::my_config'
- Fixed pref loading code being susceptible to corrupted files; old user names
  were lingering over through iterations of the while loop
^ Ok, auto-detach works
^ Hmm, occasional corruption on preference save -- i think autoserver varialbe
  is being modified under us??
- Fixed... i think?? mk_ppchar can, and probably was modifying it??
- Fixed memory leak in auto-connect, argv[0] not being freed after call to CONN
   command
* We now Make sure original user file is destroyed first, to avoid garbage being
   left over
- Fixed 'save' command not returning 1 :-P
* Removed `autopass' command and associated cruft
+ New macros:
    DECLARE_HELP_ENTRY()
    HELP_ENTRY()
    __HELP_ENTRY()
    Part of the new help system -- see messages.h and help.cc
+ New file: help.cc -- this is where the help messages will be
  declared. Updated Makefiles accordingly

Wed 10-24-01
+ 'set' with no arguments now displays current preferences
+ Made admin-ization set all possible config options
+ Added 'allowed', displays config options for the current user
- Fixed user_options::set() with strings not deleting memory.
- Fixed user_options::save() -- now saves prefs for good.
- Fixed "STATUS" command gimpy output


Tue 10-23-01
* Continued changing configuration constants
+ Added user_options::match_cmd() to assist 'set' command
+ Implemented 'SET' command -- needs testing!
* Move save() and load() option loading code to class user_options
+ Added user_options::decide() to figure out what preference user has
   on a certain feature and if the config allows it in the first place.
- Fix destroy_list<>() crash on null list
- Fix crash on invalid user config in config file (user was
    being de-allocated twice)
^ So.. we have a more configurable system now. There are numerous issues:
   -- Testing needed
   -- What do I do, if user wants to enable a feature, but it's disabled? Set
       it anyway? It won't go through because of checks, but hmm
   -- Issues remain with default user. Make sure his options don't get saved, and
       it will be all good.

Mon 10-22-01
* Changed up the user_options structure and interface quite a bit ...
+ All user_options elements now private
+ Added user_options::set(..), get(..), and friends to access
   internal variables
+ Added user_options::checkf(), clearf(), get_flags() to access flags
* We have 'preferences' now -- basically so user can choose to disable dcc
   proxying if its enabled, for example
+ Added user_options::checkp(), clearp(), get_prefs() to access preferences
* Moved several variables from conn class, now stored in user_options



Sat 10-13-01
+ Added output for Rehash and Save commands
+ Rehash now does user option reloading at least
- Fixed autoserver not being read at all in the sscanf() calls in the
    option loading


Tue 10-09-01
^ Decided that each will conn will make copy of its users' configuration
  structure. conn::config will point to it. userdef::cfg is seperate

Wed 09-26-01
+ added hooks for "trace" -- it will be a neat little command whenever
  i get around to it.
^ stared blankly at the ruleset code for a few minutes. Nope, you really can't
  code when you'd rather be sleepin


Tue 09-25-01
* Some changes to logfile retrieval:
   -- id is now totally ignored
   -- username is now checked in logfile::find (wasn't before)
   -- password is optional.. if none specified, only files with
      no password will be returned
   -- not possible to get logfiles of other users
   -- default users must specify password
- fixed null password crashing logfile::find .. null password
   now changes to "none", which is how we will treat null passwords
  from now on in the logfile storage system.
* log find now deletes the list if it can't find anything, instead of
   leaving behind an empty list, which messed up the 'log list' command.
+ we now have a spiffy login screen !!
+ new member: conn::detach_time .. only purpose is to provide a duration
   reading while the user is detached
^ Tested mdidentd... it still works. No reason that it shouldn't. Just that
  with all the new xinetd crap and all that lately, people dunno how to
  get it working. So we will update the documentation... sometime.
^ Some stupid fchmod issue with mdidentd... it don't seem to work. Maybe it's
  a linux thing.. can't use it on Unix domain sockets or something.. I dunno!
  It pissed me off, so I added an extra call to chmod, and now all is dandy.
  /var/run/mdidentd created w/ proper permissions.
- Fixed vhost command


Sun 09-23-01
^ ccmalloc doesn't work anymore.. not sure why..
^ note: killing zombies still works. need to look
  into that...

Fri 09-21-01
* Change a few things in the 'hash' command.. reduce precision
  of percent-amounts to 1..
+ Finished up hash command.. specify an option 1-3, will show stats
   for both command parsers and config file parser.
- Fixed problem in reattach... was duplicating argv[4] in channel...
   ignoring the stuff after it.. causing only one channel to be
   joined.
- Fixed crash in sessions command: oops, forgot to check for
    non-existant user.
^ I am chasing the ruleset issue... we're gonna resolve this soon.


Thu 09-20-01
- Fixed mk_ppchar() allocating with strdup() (malloc()), since
   we were using delete[] to free that memory!
- Fixed mk_ppchar() messing up with zero-length strings.
- Fixed ezb command with no arguments causing problems.
- Fixed WHOIS command being gimpy if you gave it a connection ID.
* Cleaned up conn.h... re-organized somethings, and noticed
   failed_admins is now unnecessary.. and removed it.
- log_options works again
* Renamed conn::send_client() to conn::cprintf().
   Just thought it would be neat.
+ Added support for reattach command to reattach to another
  user.. Currently only supported by Admin users.
- Fixed crash if 0 return from command handlers
* Logfile will now use password "none" if null string is given.
  Similarly, we will search for "none" when we do that.
- Fixed crash in 'login'
- Fixed stupid crash in DCC proxying -- order of statements got messed,
    was dereferencing null pointer.
^ Note: several issues now with logfile storage. Now that we have user names,
    we can't afford to store them as nicks anymore.

    I think.. store the username (including default).. DETACHed id (not user id)..
    and the password if its there..

    Thats the same method pretty much, but a few changes are needed.. but we will
    see.
+ New type: __htbl::hash_stat_t (for use in hash table stat interface)
+ Did the HASH command, finally.. dumps out some very basic stats.
  Kinda useful.
^ (overall, command parser was made a lot more stable)

Wed 08-22-01
^ Wondered why destroy_list didn't work. Didn't figure it out totally.
  But putting the function in linkedlist.h seemed to fix it. Hmm.

Friday 08-10-01
- Checked dcc proxying (both ways) and ctcp ping handling while detached.
   Both work now, as far as i can see. It might be a good idea to do some
   legit testing with the DCC proxying, as in use one of my LAN boxes
   and a client off a shell.
* change to gettok() for some command handlers cause they need more than
   one token.
+ Added lookup-by-id for WHOIS
* abolished obj_set

Saturday 08-04-01
- Fixed fast server-connect in pass/login command causing crash
- Fixed and cleaned up log command a bit.
- Fixed a crash in "login" command
- Fixed mk_ppchar returning incorrect # of tokens

Thursday 08-02-01
- Fixed parse() and parse_incoming(), made cleaner, but still
  there is an strcpy() that can be avoided.
^ ezb command is broken, oops, never implemented with new system
- EZB command finally fixed, minutes later

Wednesday 08-01-01
* Got it to compile with new argument system.
- Fixed a crash with new system
^ In fact, new system needs to be well tested, cause
  right now, you can't even send messages, cause PRIVMSGs
  are being filtered and dropped somewhere.
  Hmm.
  The paths need to be analyzed after the argv[] table is assembled and
  parsed. Cause sometimes argv[0] needs to be deleted, and sometimes the raw
  line buffer needs to be sent. It is kinda messy now...
* Cleaned up parse().. it's a lot simpler now. however still needs some
  tweaking, in particular there is now an extra strcpy() operation for
  every privmsg sent and for a few other commands.


Saturday 06-02-01
+ Added hooks for SET, ECHO
* Ok, default user can use 'sessions' now. It was the easy way
  out. No use forcing them to memorize raw ID numbers.
+ Wrote some basic option saving code. It is horrible.
- Admin flag was not being preserved across detach
+ Added mk_ppchar() from previous experiment to conn.cpp
+ Began conversion to int argc, char *argv[]
   based command handlers. It is a bitch. A lot of crappy code found
   in the process, and a thorough clean up of the command handlers
   would not be a bad idea.

Thursday 05-31-01
^ How to store user settings??
+ Unified the debug output interface. Yay.
- Fixed a lot of the #include massive-recursive crap. It is a lot cleaner,
  maybe this or something else caused the resulting ezb executable to
  be over 20kB smaller than before. Hmm.

	

Monday 05-28-01
* Make sessions command work for default user for now

Sunday 05-27-01
- Socket code works again.

Sunday 05-20-01
* No longer abort() on full sock table
+ Added checks for full socket table.

Wednesday 05-16-01
- Reimplemented vhosts. It took about 10 minutes. Wow.

Monday 05-14-01
+ Wrote a bit more of the whois command


Wednesday 05-09-01
- Oops, config file parser was chopping lines to 30 chars.
+ Skeleton for whois command

Saturday 05-05-01
- Fixed reattach
* dynbuff::add() will now return bytes added rather than the new
  size of the buffer
+ Added `traffic' command. Useless command to show bytes sent
  from here to there. Does not log everything at the moment. For
  example, any sends with fdprintf or send_client() are not accounted
  for. Neither are DCCs.
+ Added greeting when logged in. Also shows detached connections
+ Implemented some configuration checks before loading completes.


Sunday 04-15-01
+ Redid reattach command, detach() to support new system
+ Added "attach" command as alias to reattach
* Removed away-msg functionality from detach command for now.
  There will be a better way perhaps later.
* Now using one big global buffer instead of several static
  ones for the various printf-style functions in the code. Saves
  3K of mem.
+ Implemented new admin system and default user detection

Saturday 04-14-01
+ Added 'sessions' command to list detached sessions
- Removed several stray arguments to fdprintf calls in
  status command handler. Dunno how they got there.

Friday 04-13-01
^ Now compiles. Managed to even connect to an IRC server.
+ Ok, LOGIN now works.

Thursday 04-12-01
+ Wrote a basic "LOGIN" command
^ Spent over an hour trying to get the rest of the program to
  compile. Some huge sections of code are commented out: some are destined
  for deletion, others just currently unsupported.
  A lot of work remains..

Tuesday 04-10-01
^ Decided that:
  The user registration and login process is as follows:

  1. client connects:
     - connection accept()'ed, vars initialized
     - shitlist checked to see if client is banned
     - master userlist checked to see if a possible user
        exists for this connection
     - If on shitlist, or no possible users exists, client is
        dropped
  2. client sends user/nick combo
     - data copied, nothing happens
  3. The following can happen:
     A. The client sends LOGIN <user> <pass> [auotserver params]
     or B. The client sends PASS <user>:<pass> [autoserver params]
        - add() called for <user>
           * checks that user matches hosts and password
           * returns reason if banned
           * Register w/ rulesets here

     C. Client sends PASS <password>
        - same as above, but search done for "default" user.

   4. When nick,user and pass are received
       on_client_connect()



Monday 04-09-01
+ Tired, wrote ruleset::is_allowed_list to search a list and see if
  user is allowed.


Friday 04-06-01
* Not much work done today, messed around w/ various sections
  and decided to replace the inefficient fd->socket object lookup
  routine with a big array. This means a default hard limit of 256
  sockets

Thursday 04-05-01
- Fixed the problems found yesterday w/ the block parsing
* Decided that max-failed-passwords and max-reigstration-time belonged
   as proxy options

Wednesday 04-04-01
- Fixed several problems w/ grab_block(). I forgot exactly what i did...
* remove_tabs() got removed
- Fixed several bugs throughout the parsing code.
* Changed abort() calls to useful error messages and
   return 0's
^ Parser now succesfully loads a config file with most of the
  current config options, and is fairly robust. Unknown commands,
  invalid constructs, missing parameters, and garbage are detected
  w/o crashing.

  todo: empty blocks are causing problems. blocks w/o spaces between
        them are also failing. user { ] blocks without usernames
        are not being detected


Tuesday 04-03-01
+ More work on parser. Implemented ruleset doing and
  user blocks.
* Abolished misc_block
* Abolished admin_block
* Had to remove user_option_t and server_option_t for various
  reasons
* Renamed rule_set to ruleset. It was a bitch to convert,
  but the underscore seemed unnecessary and was irritating me.
+ Wrote skeleton for userdef (in user.h), also moved user_options
  structure and flags there.
^ Late night, got it to compile and link. ezbounce.o and config.o, that
  is, with some amount of #if 0'ing and funky commands.
  grab_block is quitting early with nested blocks. i am pooped, will
  investigate tomorrow

Monday 04-02-01
+ Added new symbol table for config file parsing.
+ Added strip() function to elegantly do the comment char detection
  and space and tab removal from each lines.
+ Added parse_block() function, reads a block (chunks between { }, or
  even the whole file) line by line, calling the symbol lookup function
  and doing the proper checks and helper function calling for each
  command encountered.
+ Added get_block() to obtain chunk between curly braces.

Sunday 04-01-01
* Started work on the new config parser:
+ new types: server_option_t and user_option_t,
  as well as struct user (holding the definition
  of a user), proxy_options (global options for the ezb
  proxy), user_options (options configurable on a user level)
  and a hash table for the config file parser symbols.
* Deleted most of the original parser code.

Saturday 03-31-01
^ All night LAN parties are mutually exclusive w/ coding


Monday 03-26-01
* Renamed linkedlist class to list

Sunday 03-25-01
^ All night LAN parties are mutually exclusive w/ coding

Thursday 03-22-01
* Abolished do_command()
* (new command stuff seems to work)
- Removed send("\r\n",...) calls. The CRLF characters are added to the end of 
  the buffer and sent in one system call now.
+ Added new command handlers, hash table for parsing of incoming data.
+ Moved all the incoming traps to their respective cmdfunc's
* Abolished match_command()

^ now... something is wrong. BitchX is not convinced of the server change
  like it was before when we connect. I dunno why, maybe something is not
  being relayed..
^ Ok found the stupid ass bug. Put the '\n' in the wrong place. One
  byte of garbage was sent w/ the next packet.... Everything apparently
  works well now.

Wednesday 03-21-01
+ Added NDM flag to conn status.. a hack to allow ezb command to have its
  handler function, for privmsg and quit to have handlers, and for ezb command
  to work full time.
* Finished conversion of all from-user command handlers.

Tuesday 03-20-01
+ Implemented the handler function calling and crap for the new system
- Fixed ToUpper()
* Changed check order in the command matching so that the flags are checked
   first rather than the strcmp()
* To put ezbounce, QUIT, and PRIVMSG handlers in a cmdfunc? Would clean up
  the code some, but would take some hacks to get it working right. For example,
  if 'ezb' were to match through the hash lookup, then everything else will too
  because normally no searching is done when bounced.

Monday 03-19-01
+ Added CMDFUNC() && __CMDFUNC() macros for the command handlers
* Began moving stuff out of do_command to relevant handler functions
+ Added ToUpper() to capitilize a whole string (needs debugging?)
^ do_command -> CMDFUNC() move complete. Compiles, need to implement
   the rest and test it out.


Sunday 03-18-01
+ New files:
    hash.h, hash.cpp: skeleton hash table
    commands.cpp, commands.h: the new user-command parser
      and handlers
* Removed conn::command_set, replaced w/ struct cmd,
    which is the same except the help pointer is
    replaced by a pointer to a function: the command handler.

^ ... this means i've decided to abolish the gigantic (~500 lines)
   switch() for the command handlers, everything will be in its own
   function now of type int handler conn::func(int id, char *). The int
   argument is for the id #, allowing a handler for multiple
   commands.
* Added CMD_ prefixes to relevant id #s.


Friday 03-16-01
^ Messed around with hash tables as an alternative to the
  linear lookup that is currently used for the user command
  parser.


Wednesday 03-07-01
- Prevent killing of zombies.
- Argh, stupid private logging bug. Was writing to -1 if
  logging private and only private.


Friday 03-02-01
+ Documentation updates
+ Added the man page that karl sent.. oh long time ago.
  It still needs a little work.
... Released 0.99.12
  Lots more work can be done...

Wednesday 02-28-01
+ Added support for UnReal IRCD '*' and '^' channel
  user modes.
^ Tried to change conn id allocation, so that it would use
  any holes in the sequence instead of always incrementing. Couldn't
  think of a way right now to do it w/o eventually walking the whole
  list of conns at some point. In fact, many times. Will look into this
  later.

Saturday 02-24-01
* Changed auto-detach crap. There is now just one
  set 'enable-auto-detach' variable. You must /quote
  ezb quit.

Tuesday 01-30-01
+ Added anti-idle thingy for detached connections
* Revised some of the timer code
* Admin needs password now to reattach

Sunday 01-14-01
- Fixed unused parameter warnings on some compilers


Saturday 01-13-01
+ Added further handlers for POLLERR/POLLHUP. I'm not sure this 
   will totally cure the poll() infinite loop problems though.
- oops, select()-based socket code was crashing.
- fixed that..
- 0.99.11 released

Sunday 12-24-00
- Applied Karl's mdidentd return code fix patch

Thursday 11-23-00
+ Added select() implementation for pollsocket system. In some ways it
   is actually cleaner. How stable is it.. we will see.
+ Added --use-select option to configure to force use of select() for 
   socket code
^ Found an exploit against 0.85.2 involving a buffer overflow in the 
   nickname storage. Recent versions are not affected, because a limit
   on nickname length is enforced, rather than a flat out my_strdup 
   on the whole string obtained from the user.
* Increased listen() backlog to 20.
+ Now sends ERROR string after being killed and detaching.
  

Tuesday 10-31-00
- Fixed null pointer dereferences in timer code.
- Released 0.99.10

Friday 10-13-00
- Fixed random permissions occurring on pid file (added fchmod call)

Thursday 10-12-00
^ Released 0.99.9

Monday 10-09-00
- Fixed compile issues under RedHat 7/GCC 2.9x

Sunday 09-10-00
^ Welp, a month hiatus isn't very productive but time has been
   against me lately. But here goes..
* Outgoing DCC Proxying now done with real sender ip being used
^ dccpipe constructor assumes ip and port are in host order. is this
   the right thing?

Wednesday 08-09-00
* Changed timer system from itimer based to a simple system
   that adjust the poll() wait time so we get the right checks
   done very 30 seconds.
* alarm() is back for DNS timeouts (still doesn't do jack 
   on glibc(?) tho)

Sunday 08-06-00
^ ... tested again finally and it works. Gotta decide what to do
   tho.
* Cleaned up some old cruft in conn.cpp. 

   

Wednesday 08-02-00
^ Well, incoming DCC Proxying seemed to work. Outgoing didn't.
   Found that we never called bind() when connecting to sender.
^ Well I was wrong. Bind() is not needed at all. Just need to know
   where we're connecting to do. And that is where the problem lies..
   Turns out mIRC is setting its local host to global ip by /whois'ing
   itself and not using LAN Ip. This is reflected in the CTCP DCC commands,
   from where we extract the senders ip and port.
* Fixed several possible crashes in dcc.cpp. Call close_all() and you must
   exit.
^ Handling of POLLERR & POLLHUP: poor. It seems to occur on connect errors,
   and we can apparently do a recv_test() to find out why. 
* Wrote a handler for this in dcc.cpp: However, a recv_test() would also be 
    nice
^ Noticed DCC being killed in 5 seconds due to time out: recheck timer code.
   Something is screwy somewhere.
^ Need to decide on DCC proxying, if to use the real IP address of the 
   sender or the one he provides in CTCP DCC? The latter would give users more
   flexibility... not sure what do to
^ After realizing the true problem behind the proxy issue, i tested again 
   and...


Tuesday 08-01-00
^ Hmm... odd DCC Proxying issues. A basic test from my lan failed. I don't
   know if its this new code, or if the code was originally fscked.
   100% CPU usage in one stage of the process. Investigating........ 

Saturday 07-29-00
+ Half assed solution for DCC time outs.
^ This timer system is not the best thing. It works
   for now and I'll leave it in. A better solution is to
   control the timeout value for the poll() call to make sure
   that every 30 seconds we do the needed checks.
   Right now I want to make a release. It's been way too long.
+ Fixed a bug in list_iter postfix increment/decrement.
   Basically wouldn't work if there was no previous or next item.
* Removed unnecessary "dumping logs" message.
^ Released 0.99.8

Friday 07-28-00
+ further documentation updates (config files)
* Now using set/getitimer for all timer needs
+ New timer code in server.cpp; alarm_handler() sets
   flags which are checked by check_timers()
^ Well, alarm() interferes with itimers. So I got rid of all 
   alarm() calls...
   and also I noticed alarm() has never really interrupted
   DNS lookups on glibc
   In any case, an alarm is delivered every 30 seconds so the
   DNS lookup will be interrupted eventually.

Wednesday 07-26-00
+ Added the checks for poll() and #errors about not having it
- Fixed potential null pointer de-reference in conn:kill()
- Fixed another null pointer dereference for 'write' command
* Moved conn::msg_xxxx cruft to messages.h
^ Tested several DCC events and combinations. Seems to work
   fine, MD5Sums check out.
  
Tuesday 07-25-00

+ Added the auto-away thing to detach.
+ Updated the documentation in README. Documenting all the 
  config options is what remains. Need to check sample.conf..

Monday 07-24-00

* Changed logfile searching and sending to unlimited.
* Storing results in conn::loglist of type obj_set<char> *
^ Should I make an string list class or something.. to 
    use in managing the locked logfile list as well as
    the search result list.. Maybe later.
+ Wrote pollsocket::compress() -- it could be better though..
- Fixed being able to set log options w/o specifing c,p or a.
* Changed several simple member functions to have a const property.
^ pollsocket::~pollsocket(): num_pfds is decreased in some cases but 
    sizeof allocated memory remains the same.. investigate! 

Sunday 07-23-00

+ Added "auto-connect-server" option to connect automagically 
    upon registration.
* Moved conn command handler to its own function to facilitate
    new auto-connect-server option.
* gettok() call to obtain value for do_set_command() now uses
    get_rest argument.
* Eliminated conn::get_client()
    Replacement is conn::addr(); data to be stored permanently in 	
    user.fulladdr and not recalculated everytime.
    (id: %d) syntax becomes obsolete under above system
- Fixed incorrect use of htons() in many places. Should have used
    ntohs() when decoding sin.sin_port. Didn't seem to matter on i386
    machines though.
* Redid detach/reattach ruleset issue. Store result of 
    getsockname(client->fd) port and user's ip in a local_saddr and
