This switches from somewhat gory string parsing based on strncmp() and next_arg() to a simpler alternative
based on sscanf(). I think these are much easier to understand now, and shouldn't have any subtle bugs
lurking like the old code.
This also removes support for some obsolete messages that don't seem to be in any modern ircds:
"Identd reponse differs"; bot messages like "Rejecting vlad/joh/com bot:" except for "is a possible spambot"
which is still in use; and the "High-traffic mode" messages.
Previously, SWATCH NONE meant "show no server notices" if OperView was
enabled, but "show all server notices" if OperView was disabled. Now,
it always means "show no server notices" (the default SWATCH is ALL,
so the default will behave the same).
This allows us to simplify the code a great deal as well.
Also trim off leading "***" if the server messages are handled by
handle_oper_vision(), as they already are in parse_server_notice().
Using strstr() here is entirely wrong. The intention is to catch notices
prefixed by *** or similar, and that's already detected further up in the code,
stored in the flag variable.
serversay() calls add_last_type(), so there's no need for the callers to do so
as well.
Remove the first argument to serversay() because it was always called with 1
anyway.
This was broken in commit [07cdd587], where 'sizeof' was used on a pointer
instead of the buffer pointed-to.
Fix this by having the caller of ircop_flags_to_str() supply a buffer and
length, since there's only two callers and both can use happily use stack
objects.
Remove the extra space in the default /fset SERVER_NOTICE, and similarly
the extra space in the HUMBLE /set SERVER_PROMPT.
The code in the client always _intended_ to add a space between SERVER_PROMPT
and SERVER_NOTICE_FSET but a bug in 75p3 and below meant it that it didn't.
This bug was fixed in 1.0b but the formats were never updated.
Also remove replace the embedded ANSI in the default SERVER_PROMPT with
% color code.
We don't know the server's proper name until registration, so the test against
that isn't reliable. We shouldn't be able to receive messages from anyone else
until we're registered, so this should be safe.
This requires changing serversay() to accept the from name instead of the
from_server. While we're there, replace the use of alloca() with simpler
logic based on m_sprintf().
The old code would return "omain" rather than "domain" in this case.
Also remove unneccesary checks on the return value of get_server_itsname() -
this function already falls back to 'name' if 'itsname' isn't set yet.
This hook and format are used for NOTICEs where the destination isn't
a channel and isn't yourself - eg. global targets like $$*.org. This was
already the case for PRIVMSGs (using the MSG_GROUP hook and format).
Previously these were being routed like a normal NOTICE, and those don't
display the target, so it looked exactly like a private NOTICE to you.
This will also catch server notices sent before you're registered.
Functions display_msg() and check_sync() are only used in numbers.c, so they
can be static.
Remove inclusions of <numbers.h> from .c files that don't need it.
Some systems need <sys/sockio.h> for the SIOCGIFCONF ioctl - this switches
to using a proper configure check for that header rather than just assuming
it'll be there if we can't find SIOCGIFCONF. Should be more robust.
Only include <netinet/in.h> and <sys/socket.h> if the system supplies them.
This is necessary to try and get the mingw32 build working again.
No need to include <sys/types.h> and <netinet/in.h> from cdns.c - these are
already included by <irc.h>.
Instead of showing a meaningless pointer value for Screen:, we show the
screen number and ttyname.
Also take the CO, LI values from the window's screen.
Don't show the Prompt: unless one is set.
Someone reported being unable to connect with the error "Address family not
supported", which is probably being returned by socket(). It is likely a
system where getaddrinfo() is returning AF_INET6 addresses, but socket()
won't create AF_INET6 sockets.
To handle this case, we loop over all the addresses returned by getaddrinfo()
until we find one that socket() will accept.
This ensures that the saved-set-gid is also set, although this shouldn't
matter in practice since we always call execve() soon after, which
overwrites the saved-set-gid with the effective gid anyway.
Change the all: target in the toplevel Makefile so that it doesn't try to
resolve build dependencies at the top level - instead, it just recursively
builds the all: target in source/ and dll/.
Change the all: target in the source/Makefile so that it builds the EXTRAS
(scr-bx and wserv) as well as the main client binary.
The upshot of all this is that one "make" invocation is responsible for both
scr-bx and wserv, which is necessary for parallel make (make -j) to work
correctly as these binaries share some object files.
There's several different types of DCC offers, all of which need slightly
different handling. Previously they were all handled by the monster function
register_dcc_type() - this breaks them out into seperate functions for handling
SEND, RESEND, CHAT and BOT offers, moves common code into static helper
functions and renames the entry point from ctcp.c to handle_dcc_offer().
This will allow adding a way for modules to register DCC offer types that
they're interested in.
This also moves rename_file() from misc.c into dcc.c, where its only user is.
The last two arguments are port, then offset (as per the DCC ACCEPT CTCP
command). We don't really use these anyway - port is passed to dcc_create()
but for pre-existing DCC entries all that did was add it to the socketinfo,
which doesn't seem to have any real effect.
Also fix dcc_create() so it passes the actual remote port to add_socketread()
(as above, this doesn't seem to have any real effect but is consistent with
the other code).
This improves the client messages - eg previously the message to tell you that
you could use /DCC RESUME never got shown due to a logic error.
It also won't try to auto-resume if the local file is already the same size or
bigger than the incoming file.
Mark DCC connections that we have requested RESUME on, so that we know
whether or not to act on a DCC ACCEPT that is received.
Also fixes up a slightly wrong message in /DCC RESUME.
DCC_CNCT_PEND was only ever set, not tested, so it was pointless.
There's no point only defining DCC_SSL when HAVE_SSL is defined: we can't
re-use that flag bit anyway, so might as well just define it always.
Also fixes a "flags && DCC_WAIT" that should have been "flags & DCC_WAIT".
This has no practical effect though I believe, since as far as I can tell
DCC_WAIT would always be set at that point anyway.
This also fixes a few others - eg /KBI now kicks-then-bans, and
/BKI bans-then-kicks (previously these were the wrong way around).
Reported by profiler.
The old code created a new stack frame in parse_line_alias_special(), then
another one in parse_line(). This prevented $functioncall() from working,
and made the output of CALL look odd.
|Rain| mentioned this years ago in starman.irc.
close_server() should call clear_server_queues() on the server that's being
closed, not from_server. This also lets us remove a few other calls to
clear_server_queues() that are right next to calls to close_server().
Channel WALL notices now have to match "[%Wall%/%] *", and have to be for
a channel that the client is actually on. Otherwise, they just appear as
ordinary NOTICEs.
We pass through ANSI just fine in PRIVMSGs, so we might as well treat
NOTICEs the same way too. The old code wasn't just stripping them out,
either - it was turning them into printable garbage.
stripansi() actually just munged control-characters, so it just turned ANSI
codes into visible junk.
stripansicodes() instead leaves control characters alone but removes complete
ANSI sequences from the string. I'm not sure if even that is necessary,
really - after all, we always allowed ^B, ^C etc style formatting in CTCP
replies.
get_reason() is then used only for the implementation of get_kick_reason()
and for the $getreason() scripting function. Add current nick as an
explicit argument for get_reason(), which pushes all use of from_server
out of the ransom reason functions.
Also switch a few instances of send_to_server() to my_send_to_server() where
the current server has been returned by prepare_command().
Previously only send_kill() used BitchX.kill - the other KILL commands (eg.
/WHOKILL) were using the random kick reasons. Standardise them all on
BitchX.kill, and add this file to the source so it can be installed along
with the other random reason files.
Rename randreason() to fread_random() to better reflect its function,
and change it to a one-pass algorithm. Have it write into a caller-provided
buffer instead of a static buffer. Fixes a file leak when an empty
file is given to this function.
Change freadln() so that it never returns an empty line - it only returns
0 at end-of-file now. This simplifies its callers.
Factor out some common code from the several get_reason()-type functions,
which greatly simplifies them.
Re-checking the command name to see if it's a timed ban means that the
compiler can't see that it's the same check.
This also makes sure you can't specify a negative timeout.
Initialise ip_str so that it isn't used uninitialised.
Don't strip server flags from user@ portion of the hostmask, so that it will
not miss matching bans.
Switch ip_str from alloca() to malloc_sprintf() / new_free() - there's no
particular need for alloca() here.
This silences a few compiler warnings.
This also cleans the function up by removing some always-true checks.
I'm not convinced that this function makes a whole lot of sense, though.
Will look into it further...
This function is only used by the GUI menu code, so we don't need to
build it for normal builds.
Also clean up some unsigned char / char mismatches that the compiler warned
about.
A few places created strings based on the terminal width, using fixed-sized
buffers and without checking for overflowing them. Fix those, and also
replace all other sprintf() calls with snprintf().
Reported by cpet.
Chatnet doesn't use the odd 310 numeric support anymore, it now uses 310 for
the same WHOIS_HELPFUL as Dalnet. They apparently use a pretty bog-standard
Unreal ircd now.
This code appears to be some kind of backstop so that the client will notice
a server connection that's died because of a network interruption. Checking
errno that was last set christ-knows-where is not the right way to do this,
though.
The normal write to the server for the lag check should eventually see the
host/net unreachable error if this happens.
Previously /STACK would not accept just the initial part of a /SET name
even if it wasn't ambiguous. Now it uses the same matching behaviour
as /SET.
This also removes an unused variable in do_stack_set().
Previously the server lag check was run by update_clock() if the number of
seconds since client startup was a multiple of 20 (unless it had already been
done this second). This meant that if update_clock() was not being called
frequently (eg. if your IRC connection was very quiet), it might go a long
time between lag checks.
This commit adds a /set LAG_CHECK_INTERVAL (defaulting to 30). For each
server, a lag check ping is scheduled for every LAG_CHECK_INTERVAL seconds
after the connection is finalised/registered. Setting this value to 0
disables the lag check pings entirely.
The old code set the lag to 'unknown' immediately after sending out a ping,
which meant that it was quite unpredictable how long the lag value would
stay around for. The new code only sets this once the current lag value
has become stale (ie. a ping reply is overdue based on the current lag
value). If your lag is staying the same or reducing, you shouldn't see
the [Lag ??] at all.
An absolute wake time is now calculated and updated by set_server_bits(),
TimerTimeout() and tclTimerTimeout(). This is then used to calculate the actual
select() timeout, instead of having those functions calculate a relative timeout
value themselves. This significantly simplifies those functions, since the
underlying values tend to be recorded as absolute times.
It also allows us to disentangle tclTimeTimeout from TimerTimeout(), and move the
responsibility for calculating the QUEUE_SENDS wake time from TimerTimeout() to
set_server_bits() where it belongs.
The QUEUE_SENDS and CONNECT_DELAY wake up times will also now be correctly
calculated, based on the last sent time and connect time respectively.
The DOUBLE_STATUS_LINES /SET has existed for a long while, but setting it has
never actually had an effect. This change causes it to affect the
/window double setting of new windows: 0 means new windows are created without
double status lines, 1 means only the first window is created with double
status lines and subsequent windows aren't (this is the default) and 2 means
that all windows are created with double status lines.
Note that setting this variable in your .ircrc can't actually affect the first
window, because that's created before the .ircrc is loaded. The compiled-in
default value (DEFAULT_DOUBLE_STATUS_LINES in config.h) is the only thing that
can affect the first window.
Reported by presi.
This is preferable to using time_diff() to compare two timevals, because
time_diff() gives its result as a 'double' which only has 53 bits of
precision.
Also switch a couple of places from using time_diff() to using
this function.
Define USE_NON_CONST so that the newer TCL headers define functions in the
same way as pre-8.4 TCL headers. It will be a good idea to change to
USE_COMPAT_CONST instead at some point.
Also use ckfree() instead of free() to free an allocation returned by TCL.
If we immediately handle timers that have already expired, there doesn't
seem to be a compelling reason to add 100ms to the expiry of unexpired timers.
This means that settings like CONNECT_DELAY and CONNECT_TIMEOUT are compared
against the current time with sub-second resolution. With the old way, the
delays could be up to a second longer than asked for, which had the effect of
almost doubling the default CONNECT_DELAY value of 1.
Adding these in preparation for converting server->connect_time from time_t
to struct timeval. Also converts three existing open-coded versions over to
the new functions.
set_server_bits() now returns -1 for "no timeout", so 0 is a legitimate
return value.
io() should only update real_timeout from server_timeout if server_timeout
is not -1 (real_timeout == -1 ends up meaning "wait indefinitely").
Note that if you set CONNECT_DELAY to zero you get a lag check ping sent off
first thing in the server connection, this should be fixed.
Replace open-coded loop with strpbrk(), make the constant lame_chars string
static const and remove the unused variable 'user'.
I think LAMEIDENT might be obsolete now anyway - I can't find a server that
allows control chars in usernames these days.