This table isn't modified or referenced outside of term.c, so it can be const static.
The 'const' moves ~20K from the data segment to the text segment (on 64 bit), reducing the total size of
the BitchX data segment by 10%.
Tokens that begin with two underscores __* or an underscore and an uppercase letter _X* are reserved,
so we should avoid those for our own include guards. The standard I'm settling on for foo.h is FOO_H_.
Also define STERM_C and include modval.h in scr-bx.c.
This allows us to remove the slightly bogus dummy definition of enum VAR_TYPES from modval.h, and use a simple
macro to redirect the declaration and use of get_int_var() to BX_get_int_var().
irc_std.h is where these belong - it's where the normal declarations (via the system headers) come from on
systems which don't need the compat functions.
This change means that struct.h no longer needs to include alist.h, so it will be indirectly included in a lot
fewer other files.
As a consequence, server.h needs to include notify.h to get the definitions of those data types.
Neither compat.c nor ircsig.c are compiled different for wserv or scr-bx, so there's no reason these
binaries can't just link to the same .o files as the main BitchX binary.
This also cleans up the build rules around wserv and scr-bx a little.
init_socketpath() was building a sprintf() format string intended to be used by /DETACH to create the socket
file name. This included the actual socket path, plus a %d for the port, plus the sanitised tty name and
hostname.
Only one caller needed all this though - the /DETACH command - and the other callers (in scr-bx.c) just
wanted to truncate it to the actual socket path. The format string also wasn't safe - if the home directory
path, hostname or ttyname contained % characters these werent being escaped.
It simplifies things to have init_socketpath() just return the actual socket path, after creating the 'screens'
directory if necessary. This lets the code in scr-bx.c use it as-is, and removes the need for the global
socket_path variable. The code to include the sanitised tty name and hostname in the socket file name can
be moved to the create_ipc_socket() function.
There's no need to check access() for the socket path before trying to create it - just call mkdir() regardless,
since it will fail if the path already exists, which is fine.
This commit also adds error handling to the create_ipc_socket() function for the case where creation of the
socket file fails, and switches the chmod() and chown() for the opened file to the more appropriate fchmod()
and fchown().
The function provided (either by #define to the module table or directly in the case of scr-bx.c)
is called my_ltoa(), and the #define in irc_std.h aliases this to ltoa().
The test for p != NULL is pointless, it has already been dereferenced and modified.
The argument to tolower() and toupper() must be in the range of unsigned char.
Fix some spelling errors in user-visible messages.
remove_channel() is only called in direct response to a message from a server,
so it always acts on from_server - remove the unnecessary server argument.
The channel argument is always non-NULL - remove the dead code that removed all
channels if a NULL channel was passed.
The declaration of dcc_dllcommands in modules.c was wrong - add it to dcc.h so it's checked against the definition in dcc.c
and include it from there.
The DCC_dllcommands structure isn't structured like a "List2" so remove_module() doesn't work - use remove_from_list_ext().
Previously these codepaths were dead because it was passing an argument like "+HOST" to check_whowas_nick_buffer()
in place of the channel name, so it would never find anything.
Now that function supports a NULL channel to mean "any channel", so we can use that. The actual code itself needed to be
fixed as well, it's now similar to the way userhost_unban() is written.
The use of the whowas cache in userhost_unban() would never work, because it was passing 'args' as the channel
name which also included the window number.
Rework this substantially, including using lookup_channel() and set_display_target() in place of prepare_command().
The second branch of if (str) ... else if (str) is dead code, remove it. Also remove the if() entirely because
the while condition covers it exactly anyway.
Move the static variables used only in this function to function scope.
Change color_mod to const static and remove unneeded variable c_mod.
Move the increment of cparse_recurse to after the point where we bail.
None of this should have any user-visible impact.
pid_t is defined by POSIX to be a signed integer type, so the %u format is wrong.
Cast to long and print with %ld - it is unlikely that any real-world system has pid_t bigger than long.
Previously you could unset CMDCHARS and the effect would be to treat it like it was set to DEFAULT_CMDCHARS,
except that some code was missing the fallback (eg. ignore_last_nick()) which would make it crash.
Instead of having the fallback everywhere, just make it so that you can't unset the variable - if you try, it
sets it to DEFAULT_CMDCHARS. This reflects what the behaviour has always been, it just makes it explicit to
the user and the bonus is we don't have the test it for NULL everywhere.
The 'free_it' variable was only initialised to zero at the start of the function, so when non-main screens
were processed in the later iterations of the loop, it could keep a value of 1 from the previous iteration.
We don't actually need a free_it variable at all - just use a NULL value of ptr_free to indicate that there
is nothing to free (and passing a NULL to new_free() is a no-op).
This also simplifies a test because ptr is always non-NULL (strip_ansi() never returns NULL).
If wserv is told to connect to "localhost" it might try to connect to ::1, which won't work because
the wserv socket is AF_INET only.
So explicitly bind the socket and make the connection to "127.0.0.1" instead.
Previously, INVITE and WALLOP were tracked for flooding, but if the flood triggered then the auto-ignore
didn't happen. As far as I can tell, this was just an oversight.
Using sequential constants for *_FLOOD constants means that we can use a simple lookup table to convert them
into text for display and IGNORE_* constants.
This adds a FLOOD_FLAG() macro to convert a _FLOOD constant to the appropriate flag. For now this just
casts the argument to unsigned int.
Rename Flooding.type to Flooding.flags and change it to unsigned int, to reflect that it's a bitfield of
flags for multiple flooding types.
All callers of flood_prot() were supplying { get_flood_types(flood_type), flood_type } as the second and third arguments,
except one that supplied { get_flood_types(CTCP_FLOOD), CTCP_ACTION_FLOOD }.
Hardwiring this logic in to flood_prot() lets us remove the 'type' argument without changing the behaviour.
This aligns the function with the documentation and what EPIC4/5 do. I couldn't find any example of an existing
script that actually called this function, so hopefully no-one is relying on the old behaviour.
This replaces calls to alloca() followed by two strcpy()s with a single
call to memmove(), and removes a confusing for/break structure.
The function should behave exactly as it did before.
The static 'pos' variable in check_flooding() would not stay in sync with the number of entries in
flood_list after clean_flood_list() was called. This meant that check_flooding() would always end up
removing all previous entries if it tried to add a new one.
Fix this by removing the tracking of number of flood_list entries, and just removing stale ones (older
than /SET FLOOD_RATE).
As always, the funcion pointers should be cast to the correct type before calling them, rather
than calling them with the wrong type and trying to cast the result. Fixes a warning compiling
mail.c on 64 bit architectures, and this might well have caused a crash when using the qmail plugin
on those architectures too.
Every call to create_dcc_int() was preceded by a call to parse_offer_params(), and the DCC_int
is where the address/port/size produced by the latter is stored, so this refactoring makes
sense and reduces the calling function complexity/size considerably.
Checking before truncation means you can sneak a privileged port past the check.
This change also collects the various broken-out parts of a CTCP DCC offer into a struct so that
it's easier to pass them all around together.
parse_offer_params() was being run unconditionally by check_dcc_init() even if it didn't find a
custom init_func() to call, which is the usual case. It then gets called again by the hardwired
DCC init function, which led to the error message appearing twice. This has check_dcc_init() only
call parse_offer_params() when its about to dispatch to a custom init func.
This also improves the message a bit (making it [host:port] rather than the other way around) and
combines the 'privileged port' message and "zero address" message together.
Previously waiting (inactive) file-type offers were shown different to others, omitting the
time-since-offer. Unify them to use the same format, which also cuts out a few lines of code.
Also tweaks the DCC_BAR_TYPE 1 format to include the DCC state (always Active) where the
completion bar would be in the DCC_BAR_TYPE 0 format. This just looks a bit more consistent.
get_stat_format() now returns the entire cparse string, not just the completion bar portion. This
means we don't need to call convert_output_format() twice.
This conversion (which conditionally prepends 'T' to the DCC type name depending on whether
TDCC is enabled or not) was open-coded in several places.
Also removes unused extern function get_dcc_type().
s->time on the SocketList is set to the time that the chat offer will expire, so it's in the future.
This shows up as a very large positive time. Instead, use n->lasttime as that is set to the time
when the offer is made.
Also adjust the format for non-file offers so that it all lines up properly.
This now calculates a 'pcomplete' value for proportion of transfer complete (0.0 to 1.0).
From this we can calculate most other things easily - percent complete, ETA, and the size
of the completion bars.
User-visible change is that the DCC_BAR_TYPE 1 bar now matches the % complete for the RESUMEd
file case.
The only user-visible change here is that the bar displayed for DCC_BAR_TYPE 1 is now shown
as empty for a zero-length file rather than full, matching the 0.0% complete that is shown
and the bar displayed in the DCC_BAR_TYPE 0 case.
With DCC_BAR_TYPE 1 set, the stat line for active DCC file connections was not aligned
correctly with the header (the mm:ss field spilled into the KB/s column.)
This also simplifies things by always generating the inline bar, so the only difference
between the line printed for DCC_BAR_TYPE 0 and 1 is now the format itself.
This fixes a few issues in this function - the socket type should be 'int' not 'socklen_t', the
error cases should close() the socket so it doesn't leak.
The result of read() can be -1, and if that is compared against the unsigned result of sizeof
it will be converted to SIZE_MAX. Cast the result of sizeof to a signed type.
There's no reason you shouldn't be able to use modelock as a half-op.
Also a few other minor cleanups in this function - eg. use my_send_to_server()
with the passed server number instead of implicitly using from_server.
glob_commands() would run off the end of the irc_command array if given a match that matched
the last command. It also leaked memory because it used m_s3cat() to construct the string,
then passed that to m_strdup().
This fixes these problems by reworking glob_commands(), and at the same time removes the use
of alloca() and wild_match() by using strncmp() instead to match the start of a string. Move
glob_commands() to alias.c and make it static since it's only used for aliasctl().
Change the 'name' argument of find_command() and find_dll_command() to const char * at the same
time, so that glob_commands()'s prefix argument can be const char * too.
cdcc_numpacks is unsigned, so %u should be used instead of %d.
Fix some memory leaks in /CDCC PLIST and /CDCC NOTICE where malloc_sprintf() was called
and the string never freed.
!password || (password && x) can be simplified to !password || x.
There's no need to check if a string is equal to the destination before
copying it there: might as well just copy it.
The 'channels' argument was unnecessary because the channel list passed to it would
always be from get_server_channels(server) anyway.
Changing the message argument from a protocol message format string to a plain payload
string for PRIVMSG means printf-escaping of the argument is avoided in the caller.
This simplifies the callers and means we can remove the last use of quote_it().
This change also switches set_server_away() to use send_msg_to_channels() instead of
open-coding the equivalent, which simplifies that function a lot.
We are changing the signature of a function exported to modules here; however none
of the in-tree modules use this function so it should be OK.
The use of quote_it() is unnecessary - we can just directly use my_send_to_server()
to construct the message.
Preparation to remove quote_it() entirely.
Identifiers beginning with two underscores or one underscore and a capital
letter are reserved in all contexts, including macros.
The __N macro in irc_std.h is in this space, and was conflicting with a macro
definition in gcc 5.4.0's xmmintrin.h under cygwin, making the build fail.
Reported-By: ice-man
These commands use prepare_command() to find a channel to act on, which returns the server to use.
The code should then use my_send_to_server() to ensure that it sends the command to that server -
these functions were using send_to_server() which sends to 'from_server', which means that they
could send the commands to the wrong place, for example if they were called from a hook on a
different server.
This patch was created with the following coccinelle script:
// Detects pairing preprare_command() with send_to_server() (which uses from_server)
@prepare3@
identifier s;
local idexpression c;
expression E1, E2, E3, E4, E5;
@@
(
if ((c = prepare_command(&s,...)) != NULL && ...)
{
<...
(
- send_to_server(E1);
+ my_send_to_server(s, E1);
|
- send_to_server(E1,E2);
+ my_send_to_server(s, E1, E2);
|
- send_to_server(E1,E2,E3);
+ my_send_to_server(s, E1, E2, E3);
|
- send_to_server(E1,E2,E3,E4);
+ my_send_to_server(s, E1, E2, E3, E4);
|
- send_to_server(E1,E2,E3,E4,E5);
+ my_send_to_server(s, E1, E2, E3, E4, E5);
)
...>
}
|
if ((c = prepare_command(&s,...)) == NULL || ...) { ... return ...; }
{
<...
(
- send_to_server(E1);
+ my_send_to_server(s, E1);
|
- send_to_server(E1,E2);
+ my_send_to_server(s, E1, E2);
|
- send_to_server(E1,E2,E3);
+ my_send_to_server(s, E1, E2, E3);
|
- send_to_server(E1,E2,E3,E4);
+ my_send_to_server(s, E1, E2, E3, E4);
|
- send_to_server(E1,E2,E3,E4,E5);
+ my_send_to_server(s, E1, E2, E3, E4, E5);
)
...>
}
)