places to do community service college application essay heading essay on can money buy happiness antique writing paper online essay typer essay writing services recommendations

MAX_NAME_LENGTH crash, repeatable, all versions

  • Salty
  • Topic Author
  • Offline
  • Fresh Boarder
  • Fresh Boarder
More
6 months 3 days ago #8549 by Salty
From interpreter.c


case CON_GET_NAME: /* wait for input of name */
if (d->character == NULL) {
CREATE(d->character, struct char_data, 1);
clear_char(d->character);
CREATE(d->character->player_specials, struct player_special_data, 1);

new_mobile_data(d->character);

GET_HOST(d->character) = strdup(d->host);
d->character->desc = d;
}
if (!*arg)
STATE(d) = CON_CLOSE;
else {
char buf[MAX_INPUT_LENGTH], tmp_name[MAX_INPUT_LENGTH];

if ((_parse_name(arg, tmp_name)) || strlen(tmp_name) < 2 ||
strlen(tmp_name) > MAX_NAME_LENGTH || !valid_name(tmp_name) ||
fill_word(strcpy(buf, tmp_name)) || reserved_word(buf)) { /* strcpy: OK (mutual MAX_INPUT_LENGTH) */
write_to_output(d, "Invalid name, please try another.\r\nName: ");
return;
}


The game will crash when a character with exactly MAX_NAME_LENGTH is created.

Please Log in or Create an account to join the conversation.

More
6 months 2 days ago #8550 by Castillo
Nice finding.

created character aaaaaaaaaaaaaaaaaaaa (20 chars)
and, it crash on class choosing 'M' magical user.

Please Log in or Create an account to join the conversation.

More
6 months 2 days ago #8551 by Castillo
you can try:
structs.h
struct recent_player
replace char name[MAX_NAME_LENGTH]
to char name[MAX_NAME_LENGTH+1]
seems to fix it, but i'll let thomas analyse the code in depth :)

Please Log in or Create an account to join the conversation.

More
6 months 1 day ago - 6 months 1 day ago #8552 by Krell

Castillo wrote: Nice finding.

created character aaaaaaaaaaaaaaaaaaaa (20 chars)
and, it crash on class choosing 'M' magical user.


Weird, I just did the same thing on my copy of the mud in exactly the same way and it didn't crash. I successfully went through character generation and logged into the game. 21 characters or more resulted in "Invalid name." Perhaps it's your implementation of strlen()? Maybe strnlen() might be the better option?

DESCRIPTION
The strlen() function computes the length of the string s.

The strnlen() function computes the length of the string s, up to maxlen
characters. The strnlen() function will never attempt to address more
than maxlen characters, making it suitable for use with character arrays
that are not guaranteed to be NUL-terminated.

RETURN VALUES
The strlen() function returns the number of characters that precede the
terminating NUL character.

The strnlen() function returns the number of characters that precede the
terminating NUL or maxlen, whichever is smaller.

Last edit: 6 months 1 day ago by Krell.

Please Log in or Create an account to join the conversation.

More
6 months 1 day ago #8553 by Castillo
From a fresh git clone:

rescator@rescator-System-Product-Name:~/test/tbamud$ ./configure
creating cache ./config.cache
checking for less... less
checking for gcc... gcc
checking whether the C compiler (gcc ) works... yes
checking whether the C compiler (gcc ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking whether gcc -Wall also needs -Wno-char-subscripts... yes
checking whether gcc accepts -Wno-char-subscripts... yes
checking whether gcc accepts -fno-builtin... yes
checking for gethostbyaddr... yes
checking for socket... yes
checking for malloc... yes
checking for crypt... no
checking for crypt in -lcrypt... yes
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/wait.h that is POSIX.1 compatible... yes
checking for fcntl.h... yes
checking for sys/fcntl.h... yes
checking for errno.h... yes
checking for net/errno.h... no
checking for string.h... yes
checking for strings.h... yes
checking for limits.h... yes
checking for sys/time.h... yes
checking for sys/select.h... yes
checking for sys/types.h... yes
checking for unistd.h... yes
checking for memory.h... yes
checking for crypt.h... yes
checking for assert.h... yes
checking for arpa/telnet.h... yes
checking for arpa/inet.h... yes
checking for sys/stat.h... yes
checking for sys/socket.h... yes
checking for sys/resource.h... yes
checking for netinet/in.h... yes
checking for netdb.h... yes
checking for signal.h... yes
checking for sys/uio.h... yes
checking for mcheck.h... yes
checking whether crypt needs over 10 characters... no
checking for working const... yes
checking for pid_t... yes
checking for size_t... yes
checking for ssize_t... yes
checking whether time.h and sys/time.h may both be included... yes
checking for struct in_addr... yes
checking for typedef socklen_t... yes
checking return type of signal handlers... void
checking for vprintf... yes
checking for gettimeofday... yes
checking for select... yes
checking for snprintf... yes
checking for strcasecmp... yes
checking for strdup... yes
checking for strerror... yes
checking for stricmp... no
checking for strlcpy... no
checking for strncasecmp... yes
checking for strnicmp... no
checking for strstr... yes
checking for vsnprintf... yes
checking for inet_addr... yes
checking for inet_aton... yes
checking if accept is prototyped... yes
checking if atoi is prototyped... yes
checking if atol is prototyped... yes
checking if bind is prototyped... yes
checking if bzero is prototyped... yes
checking if chdir is prototyped... yes
checking if close is prototyped... yes
checking if crypt is prototyped... yes
checking if fclose is prototyped... yes
checking if fcntl is prototyped... yes
checking if fflush is prototyped... yes
checking if fprintf is prototyped... yes
checking if fputc is prototyped... yes
checking if fputs is prototyped... yes
checking if fread is prototyped... yes
checking if fscanf is prototyped... yes
checking if fseek is prototyped... yes
checking if fwrite is prototyped... yes
checking if getpeername is prototyped... yes
checking if getpid is prototyped... yes
checking if getrlimit is prototyped... yes
checking if getsockname is prototyped... yes
checking if gettimeofday is prototyped... yes
checking if htonl is prototyped... yes
checking if htons is prototyped... yes
checking if inet_addr is prototyped... yes
checking if inet_aton is prototyped... yes
checking if inet_ntoa is prototyped... yes
checking if listen is prototyped... yes
checking if ntohl is prototyped... yes
checking if perror is prototyped... yes
checking if printf is prototyped... yes
checking if qsort is prototyped... yes
checking if read is prototyped... yes
checking if remove is prototyped... yes
checking if rewind is prototyped... yes
checking if select is prototyped... yes
checking if setitimer is prototyped... yes
checking if setrlimit is prototyped... yes
checking if setsockopt is prototyped... yes
checking if snprintf is prototyped... yes
checking if socket is prototyped... yes
checking if sprintf is prototyped... yes
checking if sscanf is prototyped... yes
checking if strcasecmp is prototyped... yes
checking if strdup is prototyped... yes
checking if strerror is prototyped... yes
checking if stricmp is prototyped... no
checking if strlcpy is prototyped... no
checking if strncasecmp is prototyped... yes
checking if strnicmp is prototyped... no
checking if system is prototyped... yes
checking if time is prototyped... yes
checking if unlink is prototyped... yes
checking if vsnprintf is prototyped... yes
checking if write is prototyped... yes
updating cache ./config.cache
creating ./config.status
creating src/Makefile
creating src/util/Makefile
creating src/conf.h
Configuration completed. To compile, type: cd src; make
rescator@rescator-System-Product-Name:~/test/tbamud$ cd src
rescator@rescator-System-Product-Name:~/test/tbamud/src$ make
gcc -MM *.c > depend

TbaMUD is freeware (it doesn't cost anything), but it is copyrighted
and has a license. You must read and agree to abide by the license before
using tbaMUD.

This message will only appear once (the first time you compile the server),
but is contained in the file doc/license.txt if you'd like to refer back to
it in the future.

Press return to read the license. Press Q to ACCEPT the terms and quit.
Q

Press return or Q to ACCEPT the terms of this license.
Press Control-C if you DO NOT ACCEPT the terms of this license.

make ../bin/circle
make[1]: Entering directory '/home/rescator/test/tbamud/src'
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o act.comm.o act.comm.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o act.informative.o act.informative.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o act.item.o act.item.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o act.movement.o act.movement.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o act.offensive.o act.offensive.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o act.other.o act.other.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o act.social.o act.social.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o act.wizard.o act.wizard.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o aedit.o aedit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o asciimap.o asciimap.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o ban.o ban.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o boards.o boards.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o bsd-snprintf.o bsd-snprintf.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o castle.o castle.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o cedit.o cedit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o class.o class.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o comm.o comm.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o config.o config.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o constants.o constants.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o db.o db.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_comm.o dg_comm.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_db_scripts.o dg_db_scripts.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_event.o dg_event.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_handler.o dg_handler.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_misc.o dg_misc.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_mobcmd.o dg_mobcmd.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_objcmd.o dg_objcmd.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_olc.o dg_olc.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_scripts.o dg_scripts.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_triggers.o dg_triggers.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_variables.o dg_variables.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o dg_wldcmd.o dg_wldcmd.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o fight.o fight.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o genmob.o genmob.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o genobj.o genobj.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o genolc.o genolc.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o genqst.o genqst.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o genshp.o genshp.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o genwld.o genwld.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o genzon.o genzon.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o graph.o graph.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o handler.o handler.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o hedit.o hedit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o house.o house.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o ibt.o ibt.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o improved-edit.o improved-edit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o interpreter.o interpreter.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o limits.o limits.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o lists.o lists.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o magic.o magic.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o mail.o mail.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o medit.o medit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o mobact.o mobact.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o modify.o modify.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o msgedit.o msgedit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o mud_event.o mud_event.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o oasis.o oasis.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o oasis_copy.o oasis_copy.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o oasis_delete.o oasis_delete.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o oasis_list.o oasis_list.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o objsave.o objsave.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o oedit.o oedit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o players.o players.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o prefedit.o prefedit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o protocol.o protocol.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o qedit.o qedit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o quest.o quest.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o random.o random.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o redit.o redit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o sedit.o sedit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o shop.o shop.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o spec_assign.o spec_assign.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o spec_procs.o spec_procs.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o spell_parser.o spell_parser.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o spells.o spells.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o tedit.o tedit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o utils.o utils.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o weather.o weather.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o zedit.o zedit.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o zmalloc.o zmalloc.c
gcc -o ../bin/circle act.comm.o act.informative.o act.item.o act.movement.o act.offensive.o act.other.o act.social.o act.wizard.o aedit.o asciimap.o ban.o boards.o bsd-snprintf.o castle.o cedit.o class.o comm.o config.o constants.o db.o dg_comm.o dg_db_scripts.o dg_event.o dg_handler.o dg_misc.o dg_mobcmd.o dg_objcmd.o dg_olc.o dg_scripts.o dg_triggers.o dg_variables.o dg_wldcmd.o fight.o genmob.o genobj.o genolc.o genqst.o genshp.o genwld.o genzon.o graph.o handler.o hedit.o house.o ibt.o improved-edit.o interpreter.o limits.o lists.o magic.o mail.o medit.o mobact.o modify.o msgedit.o mud_event.o oasis.o oasis_copy.o oasis_delete.o oasis_list.o objsave.o oedit.o players.o prefedit.o protocol.o qedit.o quest.o random.o redit.o sedit.o shop.o spec_assign.o spec_procs.o spell_parser.o spells.o tedit.o utils.o weather.o zedit.o zmalloc.o -lcrypt
make[1]: Leaving directory '/home/rescator/test/tbamud/src'
make utils
make[1]: Entering directory '/home/rescator/test/tbamud/src'
(cd util; make all)
make[2]: Entering directory '/home/rescator/test/tbamud/src/util'
gcc -I.. -MM *.c > depend
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -DCIRCLE_UTIL -I.. -o ../../bin/asciipasswd asciipasswd.c -lcrypt
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -DCIRCLE_UTIL -I.. -o ../../bin/autowiz autowiz.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -DCIRCLE_UTIL -I.. -o ../../bin/plrtoascii plrtoascii.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -DCIRCLE_UTIL -I.. -o ../../bin/rebuildIndex rebuildAsciiIndex.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -DCIRCLE_UTIL -I.. -o ../../bin/rebuildMailIndex rebuildMailIndex.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -DCIRCLE_UTIL -I.. -o ../../bin/shopconv shopconv.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -DCIRCLE_UTIL -I.. -o ../../bin/sign sign.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -DCIRCLE_UTIL -I.. -o ../../bin/split split.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -DCIRCLE_UTIL -I.. -o ../../bin/wld2html wld2html.c
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -DCIRCLE_UTIL -I.. -o ../../bin/webster webster.c
webster.c: In function ‘main’:
webster.c:31:3: warning: ignoring return value of ‘system’, declared with attribute warn_unused_result [-Wunused-result]
system(buf);
^
webster.c: In function ‘get_line’:
webster.c:156:5: warning: ignoring return value of ‘fgets’, declared with attribute warn_unused_result [-Wunused-result]
fgets(temp, MEM_USE, fl);
^
make[2]: Leaving directory '/home/rescator/test/tbamud/src/util'
make[1]: Leaving directory '/home/rescator/test/tbamud/src'
rescator@rescator-System-Product-Name:~/test/tbamud/src$ cd ..
rescator@rescator-System-Product-Name:~/test/tbamud$ ls
autorun autorun.amiga autorun.cmd autorun.pl autorun.sh bin changelog cnf config.cache config.log config.status configure doc lib LICENSE.md log macrun.pl README.md src vms_autorun.com
rescator@rescator-System-Product-Name:~/test/tbamud$ gdb --args bin/circle 5050
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later < gnu.org/licenses/gpl.html >
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
< www.gnu.org/software/gdb/bugs/ >.
Find the GDB manual and other documentation resources online at:
< www.gnu.org/software/gdb/documentation/ >.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bin/circle...done.
(gdb) r
Starting program: /home/rescator/test/tbamud/bin/circle 5050
No etc/config file, using defaults: No such file or directory
Using file descriptor for logging.
Feb 09 23:15:00 2020 :: Loading configuration.
Feb 09 23:15:00 2020 :: tbaMUD 2020
Feb 09 23:15:00 2020 :: Using lib as data directory.
Feb 09 23:15:00 2020 :: Running game on port 5050.
Feb 09 23:15:00 2020 :: Finding player limit.
Feb 09 23:15:00 2020 :: Setting player limit to 300 using rlimit.
Feb 09 23:15:00 2020 :: Opening mother connection.
Feb 09 23:15:00 2020 :: Binding to all IP interfaces on this host.
Feb 09 23:15:00 2020 :: Boot db -- BEGIN.
Feb 09 23:15:00 2020 :: Resetting the game time:
Feb 09 23:15:00 2020 :: No time file 'etc/time' starting from the beginning.
Feb 09 23:15:00 2020 :: Current Gametime: 7H 11D 4M 869Y.
Feb 09 23:15:00 2020 :: Initialize Global Lists
Feb 09 23:15:00 2020 :: Initializing Events
Feb 09 23:15:00 2020 :: Reading news, credits, help, ihelp, bground, info & motds.
Feb 09 23:15:00 2020 :: Loading spell definitions.
Feb 09 23:15:00 2020 :: Loading zone table.
Feb 09 23:15:00 2020 :: 189 zones, 13608 bytes.
Feb 09 23:15:00 2020 :: Loading triggers and generating index.
Feb 09 23:15:00 2020 :: Loading rooms.
Feb 09 23:15:00 2020 :: 12732 rooms, 2342688 bytes.
Feb 09 23:15:00 2020 :: Renumbering rooms.
Feb 09 23:15:00 2020 :: Checking start rooms.
Feb 09 23:15:00 2020 :: Loading mobs and generating index.
Feb 09 23:15:00 2020 :: 3705 mobs, 118560 bytes in index, 2134080 bytes in prototypes.
Feb 09 23:15:00 2020 :: Loading objs and generating index.
Feb 09 23:15:00 2020 :: 4765 objs, 152480 bytes in index, 1143600 bytes in prototypes.
Feb 09 23:15:00 2020 :: Renumbering zone table.
Feb 09 23:15:00 2020 :: Loading shops.
Feb 09 23:15:00 2020 :: Loading quests.
Feb 09 23:15:00 2020 :: 1 entries, 128 bytes.
Feb 09 23:15:00 2020 :: Loading help entries.
Feb 09 23:15:00 2020 :: 2652 entries, 84864 bytes.
Feb 09 23:15:00 2020 :: Generating player index.
Feb 09 23:15:00 2020 :: No player index file! First new char will be IMP!
Feb 09 23:15:00 2020 :: Loading fight messages.
Feb 09 23:15:00 2020 :: Loaded 37 Combat Messages...
Feb 09 23:15:00 2020 :: Loading social messages.
Feb 09 23:15:00 2020 :: Social table contains 490 socials.
Feb 09 23:15:00 2020 :: Building command list.
Feb 09 23:15:00 2020 :: Command info rebuilt, 766 total commands.
Feb 09 23:15:00 2020 :: Assigning function pointers:
Feb 09 23:15:00 2020 :: Mobiles.
Feb 09 23:15:00 2020 :: Shopkeepers.
Feb 09 23:15:00 2020 :: Objects.
Feb 09 23:15:00 2020 :: Rooms.
Feb 09 23:15:00 2020 :: Questmasters.
Feb 09 23:15:00 2020 :: Assigning spell and skill levels.
Feb 09 23:15:00 2020 :: Sorting command list and spells.
Feb 09 23:15:00 2020 :: Booting mail system.
Feb 09 23:15:00 2020 :: Mail file non-existant... creating new file.
Feb 09 23:15:00 2020 :: Reading banned site and invalid-name list.
Feb 09 23:15:00 2020 :: Loading Ideas.
Feb 09 23:15:00 2020 :: Loading Bugs.
Feb 09 23:15:00 2020 :: Loading Typos.
Feb 09 23:15:00 2020 :: Deleting timed-out crash and rent files:
Feb 09 23:15:00 2020 :: Done.
Feb 09 23:15:00 2020 :: Booting houses.
Feb 09 23:15:00 2020 :: No houses to load. File 'etc/hcontrol' does not exist.
Feb 09 23:15:00 2020 :: Cleaning up last log.
Feb 09 23:15:00 2020 :: Resetting #0: The Builder Academy Zone (rooms 0-99).
Feb 09 23:15:00 2020 :: Resetting #1: Sanctus (rooms 100-199).
Feb 09 23:15:00 2020 :: Resetting #2: Sanctus II (rooms 200-299).
Feb 09 23:15:00 2020 :: Resetting #3: Sanctus III (rooms 300-399).
Feb 09 23:15:00 2020 :: Resetting #4: Jade Forest (rooms 400-499).
Feb 09 23:15:00 2020 :: Resetting #5: Newbie Farm (rooms 500-599).
Feb 09 23:15:00 2020 :: Resetting #6: Sea of Souls (rooms 600-699).
Feb 09 23:15:00 2020 :: Resetting #7: Camelot (rooms 700-799).
Feb 09 23:15:00 2020 :: Resetting #9: River Island of Minos (rooms 900-999).
Feb 09 23:15:00 2020 :: Resetting #11: Frozen Castle (rooms 1100-1199).
Feb 09 23:15:00 2020 :: Resetting #12: God Complex Merged with 343 (rooms 1200-1299).
Feb 09 23:15:00 2020 :: Resetting #13: TBA Examples (rooms 1300-1399).
Feb 09 23:15:00 2020 :: Resetting #14: TBA Examples II (rooms 1400-1499).
Feb 09 23:15:00 2020 :: Resetting #15: Straight Path (rooms 1500-1599).
Feb 09 23:15:00 2020 :: Resetting #16: Camelot II (rooms 1600-1699).
Feb 09 23:15:00 2020 :: Resetting #17: Camelot III (rooms 1700-1799).
Feb 09 23:15:00 2020 :: Resetting #18: Nuclear Wasteland (rooms 1800-1899).
Feb 09 23:15:00 2020 :: Resetting #19: Spider Swamp (rooms 1900-1999).
Feb 09 23:15:00 2020 :: Resetting #20: Arena (rooms 2000-2099).
Feb 09 23:15:00 2020 :: Resetting #22: Tower of the Undead (rooms 2200-2299).
Feb 09 23:15:00 2020 :: Resetting #25: High Tower of Magic (rooms 2500-2599).
Feb 09 23:15:00 2020 :: Resetting #26: High Tower of Magic II (rooms 2600-2699).
Feb 09 23:15:00 2020 :: Resetting #27: Memlin Caverns (rooms 2700-2799).
Feb 09 23:15:00 2020 :: Resetting #28: Mudschool (rooms 2800-2899).
Feb 09 23:15:00 2020 :: Resetting #30: Northern Midgaard (rooms 3000-3099).
Feb 09 23:15:00 2020 :: Resetting #31: Southern Midgaard (rooms 3100-3199).
Feb 09 23:15:00 2020 :: Resetting #32: Midgaard (rooms 3200-3299).
Feb 09 23:15:00 2020 :: Resetting #33: Three of Swords (rooms 3300-3399).
Feb 09 23:15:00 2020 :: Resetting #35: Miden'Nir (rooms 3500-3599).
Feb 09 23:15:00 2020 :: Resetting #36: Chessboard of Midgaard (rooms 3600-3699).
Feb 09 23:15:00 2020 :: Resetting #37: Capital Sewer System (rooms 3700-3799).
Feb 09 23:15:00 2020 :: Resetting #38: Capital Sewer System II (rooms 3800-3899).
Feb 09 23:15:00 2020 :: Resetting #39: Haven (rooms 3900-3999).
Feb 09 23:15:00 2020 :: Resetting #40: Mines of Moria (rooms 4000-4099).
Feb 09 23:15:00 2020 :: Resetting #41: Mines of Moria (rooms 4100-4199).
Feb 09 23:15:00 2020 :: Resetting #42: Dragon Chasm (rooms 4200-4299).
Feb 09 23:15:00 2020 :: Resetting #43: Arctic Zone (rooms 4300-4399).
Feb 09 23:15:00 2020 :: Resetting #44: Orc Camp (rooms 4400-4499).
Feb 09 23:15:00 2020 :: Resetting #45: Woodland Monastery (rooms 4500-4599).
Feb 09 23:15:00 2020 :: Resetting #46: Ant Hill (rooms 4600-4699).
Feb 09 23:15:00 2020 :: Resetting #50: Great Eastern Desert (rooms 5000-5099).
Feb 09 23:15:00 2020 :: Resetting #51: Drow City (rooms 5100-5199).
Feb 09 23:15:00 2020 :: Resetting #52: City of Thalos (rooms 5200-5299).
Feb 09 23:15:00 2020 :: Resetting #53: Great Pyramid (rooms 5300-5399).
Feb 09 23:15:00 2020 :: Resetting #54: New Thalos (rooms 5400-5499).
Feb 09 23:15:00 2020 :: Resetting #55: New Thalos II (rooms 5500-5599).
Feb 09 23:15:00 2020 :: Resetting #56: New Thalos Wilderness (rooms 5600-5699).
Feb 09 23:15:00 2020 :: Resetting #57: Zodiac (rooms 5700-5799).
Feb 09 23:15:00 2020 :: Resetting #60: Haon-Dor, Light Forest (rooms 6000-6099).
Feb 09 23:15:00 2020 :: Resetting #61: Haon-Dor, Light Forest II (rooms 6100-6199).
Feb 09 23:15:00 2020 :: Resetting #62: Orc Enclave (rooms 6200-6299).
Feb 09 23:15:00 2020 :: Resetting #63: Arachnos (rooms 6300-6399).
Feb 09 23:15:00 2020 :: Resetting #64: Rand's Tower (rooms 6400-6499).
Feb 09 23:15:00 2020 :: Resetting #65: Dwarven Kingdom (rooms 6500-6599).
Feb 09 23:15:00 2020 :: Resetting #70: Sewer, First Level (rooms 7000-7099).
Feb 09 23:15:00 2020 :: Resetting #71: Second Sewer (rooms 7100-7199).
Feb 09 23:15:00 2020 :: Resetting #72: Sewer Maze (rooms 7200-7299).
Feb 09 23:15:00 2020 :: Resetting #73: Tunnels in the Sewer (rooms 7300-7399).
Feb 09 23:15:00 2020 :: Resetting #74: Newbie Graveyard (rooms 7400-7499).
Feb 09 23:15:00 2020 :: Resetting #75: Zamba (rooms 7500-7599).
Feb 09 23:15:00 2020 :: Resetting #78: Gideon (rooms 7800-7899).
Feb 09 23:15:00 2020 :: Resetting #79: Redferne's Residence (rooms 7900-7999).
Feb 09 23:15:00 2020 :: Resetting #83: Glumgold's Sea (rooms 8300-8399).
Feb 09 23:15:00 2020 :: Resetting #86: Duke Kalithorn's Keep (rooms 8600-8699).
Feb 09 23:15:00 2020 :: Resetting #90: Oasis (rooms 9000-9099).
Feb 09 23:15:00 2020 :: Resetting #96: Domiae (rooms 9600-9699).
Feb 09 23:15:00 2020 :: Resetting #100: Northern Highway (rooms 10000-10099).
Feb 09 23:15:00 2020 :: Resetting #101: South Road (rooms 10100-10199).
Feb 09 23:15:00 2020 :: Resetting #103: DBZ World (rooms 10300-10399).
Feb 09 23:15:00 2020 :: Resetting #104: Land of Orchan (rooms 10400-10499).
Feb 09 23:15:00 2020 :: Resetting #106: Elcardo (rooms 10600-10699).
Feb 09 23:15:00 2020 :: Resetting #107: Realms of Iuel (rooms 10700-10799).
Feb 09 23:15:00 2020 :: Resetting #115: Monestary Omega (rooms 11500-11599).
Feb 09 23:15:00 2020 :: Resetting #117: Los Torres (rooms 11700-11799).
Feb 09 23:15:00 2020 :: Resetting #118: The Dollhouse (rooms 11800-11899).
Feb 09 23:15:00 2020 :: Resetting #120: Rome (rooms 12000-12099).
Feb 09 23:15:00 2020 :: Resetting #125: Hannah (rooms 12500-12599).
Feb 09 23:15:00 2020 :: Resetting #130: Mist Maze (rooms 13000-13099).
Feb 09 23:15:00 2020 :: Resetting #140: Wyvern City (rooms 14000-14099).
Feb 09 23:15:00 2020 :: Resetting #150: King Welmar's Castle (rooms 15000-15099).
Feb 09 23:15:00 2020 :: Resetting #169: Gibberling Caves (rooms 16900-16999).
Feb 09 23:15:00 2020 :: Resetting #175: Cardinal Wizards (rooms 17500-17599).
Feb 09 23:15:00 2020 :: Resetting #186: Newbie Zone (rooms 18600-18699).
Feb 09 23:15:00 2020 :: Resetting #187: Circus (rooms 18700-18799).
Feb 09 23:15:00 2020 :: Resetting #200: Western Highway (rooms 20000-20099).
Feb 09 23:15:00 2020 :: Resetting #201: Sapphire Islands (rooms 20100-20199).
Feb 09 23:15:00 2020 :: Resetting #211: Tarot (rooms 21100-21199).
Feb 09 23:15:00 2020 :: Resetting #220: The Enchanted Kitchen (rooms 22000-22099).
Feb 09 23:15:00 2020 :: Resetting #232: Terringham (rooms 23200-23299).
Feb 09 23:15:00 2020 :: Resetting #233: Dragon Plains (rooms 23300-23399).
Feb 09 23:15:00 2020 :: Resetting #234: Newbie School (rooms 23400-23499).
Feb 09 23:15:00 2020 :: Resetting #235: Dwarven Mines (rooms 23500-23599).
Feb 09 23:15:00 2020 :: Resetting #236: Aldin (rooms 23600-23699).
Feb 09 23:15:00 2020 :: Resetting #237: Dwarven Trade Route (rooms 23700-23799).
Feb 09 23:15:00 2020 :: Resetting #238: Crystal Castle (rooms 23800-23899).
Feb 09 23:15:00 2020 :: Resetting #239: South Pass (rooms 23900-23999).
Feb 09 23:15:00 2020 :: Resetting #240: Dun Maura (rooms 24000-24099).
Feb 09 23:15:00 2020 :: Resetting #241: Starship Enterprise (rooms 24100-24199).
Feb 09 23:15:00 2020 :: Resetting #242: New Southern Midgaard (rooms 24200-24299).
Feb 09 23:15:00 2020 :: Resetting #243: Snowy Valley (rooms 24300-24399).
Feb 09 23:15:00 2020 :: Resetting #244: Cooland Prison (rooms 24400-24499).
Feb 09 23:15:00 2020 :: Resetting #245: The Nether (rooms 24500-24599).
Feb 09 23:15:00 2020 :: Resetting #246: The Nether II (rooms 24600-24699).
Feb 09 23:15:00 2020 :: Resetting #247: Graveyard (rooms 24700-24799).
Feb 09 23:15:00 2020 :: Resetting #248: Elven Woods (rooms 24800-24899).
Feb 09 23:15:00 2020 :: Resetting #249: Jedi Clan House (rooms 24900-24999).
Feb 09 23:15:00 2020 :: Resetting #250: DragonSpyre (rooms 25000-25099).
Feb 09 23:15:00 2020 :: Resetting #251: Ape Village (rooms 25100-25199).
Feb 09 23:15:00 2020 :: Resetting #252: Castle of the Vampyre (rooms 25200-25299).
Feb 09 23:15:00 2020 :: Resetting #253: Windmill (rooms 25300-25399).
Feb 09 23:15:00 2020 :: Resetting #254: Mordecai's Village (rooms 25400-25499).
Feb 09 23:15:00 2020 :: Resetting #255: Shipwreck (rooms 25500-25599).
Feb 09 23:15:00 2020 :: Resetting #256: Lord's Keep (rooms 25600-25699).
Feb 09 23:15:00 2020 :: Resetting #257: Jareth Main City (rooms 25700-25799).
Feb 09 23:15:00 2020 :: Resetting #258: Light Forest (rooms 25800-25899).
Feb 09 23:15:00 2020 :: Resetting #259: Haunted Mansion (rooms 25900-25999).
Feb 09 23:15:00 2020 :: Resetting #260: Grasslands (rooms 26000-26099).
Feb 09 23:15:00 2020 :: Resetting #261: Inna & Igor's Castle (rooms 26100-26199).
Feb 09 23:15:00 2020 :: Resetting #262: Forest Trails (rooms 26200-26299).
Feb 09 23:15:00 2020 :: Resetting #263: Farmlands (rooms 26300-26399).
Feb 09 23:15:00 2020 :: Resetting #264: Banshide (rooms 26400-26499).
Feb 09 23:15:00 2020 :: Resetting #265: Beach & Lighthouse (rooms 26500-26599).
Feb 09 23:15:00 2020 :: Resetting #266: Realm of Lord Ankou (rooms 26600-26699).
Feb 09 23:15:00 2020 :: Resetting #267: Vice Island (rooms 26700-26799).
Feb 09 23:15:00 2020 :: Resetting #268: Vice Island II (rooms 26800-26899).
Feb 09 23:15:00 2020 :: Resetting #269: Southern Desert (rooms 26900-26999).
Feb 09 23:15:00 2020 :: Resetting #270: Wasteland (rooms 27000-27099).
Feb 09 23:15:00 2020 :: Resetting #271: Sundhaven (rooms 27100-27199).
Feb 09 23:15:00 2020 :: Resetting #272: Sundhaven II (rooms 27200-27299).
Feb 09 23:15:00 2020 :: Resetting #273: Space Station Alpha (rooms 27300-27399).
Feb 09 23:15:00 2020 :: Resetting #274: Adria: Saint Brigid (rooms 27400-27499).
Feb 09 23:15:00 2020 :: Resetting #275: New Sparta (rooms 27500-27599).
Feb 09 23:15:00 2020 :: Resetting #276: New Sparta II (rooms 27600-27699).
Feb 09 23:15:00 2020 :: Resetting #277: Shire (rooms 27700-27799).
Feb 09 23:15:00 2020 :: Resetting #278: Oceania (rooms 27800-27899).
Feb 09 23:15:00 2020 :: Resetting #279: Notre Dame (rooms 27900-27999).
Feb 09 23:15:00 2020 :: Resetting #280: Living Motherboard (rooms 28000-28099).
Feb 09 23:15:00 2020 :: Resetting #281: Forest of Khanjar (rooms 28100-28199).
Feb 09 23:15:00 2020 :: Resetting #282: Infernal Pit of Kerjim (rooms 28200-28299).
Feb 09 23:15:00 2020 :: Resetting #283: Haunted House (rooms 28300-28399).
Feb 09 23:15:00 2020 :: Resetting #284: Ghenna (rooms 28400-28499).
Feb 09 23:15:00 2020 :: Resetting #285: Descent to Hell II (rooms 28500-28599).
Feb 09 23:15:00 2020 :: Resetting #286: Descent to Hell (rooms 28600-28699).
Feb 09 23:15:00 2020 :: Resetting #287: Ofingia and the Goblin Town (rooms 28700-28799).
Feb 09 23:15:00 2020 :: Resetting #288: Galaxy (rooms 28800-28899).
Feb 09 23:15:00 2020 :: Resetting #289: Werith's Wayhouse (rooms 28900-28999).
Feb 09 23:15:00 2020 :: Resetting #290: Lizard Lair Safari (rooms 29000-29099).
Feb 09 23:15:00 2020 :: Resetting #291: Black Forest (rooms 29100-29199).
Feb 09 23:15:00 2020 :: Resetting #292: Kerofk (rooms 29200-29299).
Feb 09 23:15:00 2020 :: Resetting #293: Kerofk II (rooms 29300-29399).
Feb 09 23:15:00 2020 :: Resetting #294: Trade Road (rooms 29400-29499).
Feb 09 23:15:00 2020 :: Resetting #295: Jungle (rooms 29500-29599).
Feb 09 23:15:00 2020 :: Resetting #296: Froboz Fun Factory (rooms 29600-29699).
Feb 09 23:15:00 2020 :: Resetting #298: Castle of Desire (rooms 29800-29899).
Feb 09 23:15:00 2020 :: Resetting #299: Abandoned Cathedral (rooms 29900-29999).
Feb 09 23:15:00 2020 :: Resetting #300: Ancalador (rooms 30000-30099).
Feb 09 23:15:00 2020 :: Resetting #301: Campus (rooms 30100-30199).
Feb 09 23:15:00 2020 :: Resetting #302: Campus II (rooms 30200-30299).
Feb 09 23:15:00 2020 :: Resetting #303: Campus III (rooms 30300-30399).
Feb 09 23:15:00 2020 :: Resetting #304: Temple of the Bull (rooms 30400-30499).
Feb 09 23:15:00 2020 :: Resetting #305: Chessboard (rooms 30500-30599).
Feb 09 23:15:00 2020 :: Resetting #306: Newbie Tree (rooms 30600-30699).
Feb 09 23:15:00 2020 :: Resetting #307: Castle (rooms 30700-30799).
Feb 09 23:15:00 2020 :: Resetting #308: Baron Cailveh (rooms 30800-30899).
Feb 09 23:15:00 2020 :: Resetting #309: Keep of Baron Westlawn (rooms 30900-30999).
Feb 09 23:15:00 2020 :: Resetting #310: Graye Area (rooms 31000-31099).
Feb 09 23:15:00 2020 :: Resetting #311: The Dragon's Teeth (rooms 31100-31199).
Feb 09 23:15:00 2020 :: Resetting #312: Leper Island (rooms 31200-31299).
Feb 09 23:15:00 2020 :: Resetting #313: Farmlands of Ofingia (rooms 31300-31399).
Feb 09 23:15:00 2020 :: Resetting #314: X'Raantra's Altar of Sacrifice (rooms 31400-31499).
Feb 09 23:15:00 2020 :: Resetting #315: McGintey Business District (rooms 31500-31599).
Feb 09 23:15:00 2020 :: Resetting #316: McGintey Guild Area (rooms 31600-31699).
Feb 09 23:15:00 2020 :: Resetting #317: Wharf (rooms 31700-31799).
Feb 09 23:15:00 2020 :: Resetting #318: Dock Area (rooms 31800-31899).
Feb 09 23:15:00 2020 :: Resetting #319: Yllythad Sea (rooms 31900-31999).
Feb 09 23:15:00 2020 :: Resetting #320: Yllythad Sea II (rooms 32000-32099).
Feb 09 23:15:00 2020 :: Resetting #321: Yllythad Sea III (rooms 32100-32199).
Feb 09 23:15:00 2020 :: Resetting #322: McGintey Bay (rooms 32200-32299).
Feb 09 23:15:00 2020 :: Resetting #323: Caverns of the Pale Man (rooms 32300-32399).
Feb 09 23:15:00 2020 :: Resetting #324: Army Encampment (rooms 32400-32499).
Feb 09 23:15:00 2020 :: Resetting #325: Revelry (rooms 32500-32599).
Feb 09 23:15:00 2020 :: Resetting #326: Army Perimeter (rooms 32600-32699).
Feb 09 23:15:00 2020 :: Resetting #343: God Complex (rooms 34300-34399).
Feb 09 23:15:00 2020 :: Resetting #345: Asylum for the Insane (rooms 34500-34599).
Feb 09 23:15:00 2020 :: Resetting #346: God Hall Ext 346 for God Hall Cmplx (rooms 34600-34699).
Feb 09 23:15:00 2020 :: Resetting #555: Ultima (rooms 55500-55599).
Feb 09 23:15:00 2020 :: Resetting #556: Ultima II (rooms 55600-55699).
Feb 09 23:15:00 2020 :: Resetting #653: Apartment (rooms 65300-65399).
Feb 09 23:15:00 2020 :: Resetting #654: Subdivision (rooms 65400-65499).
Feb 09 23:15:00 2020 :: Boot db -- DONE.
Feb 09 23:15:00 2020 :: Signal trapping.
Feb 09 23:15:00 2020 :: Entering game loop.
Feb 09 23:15:00 2020 :: No connections. Going to sleep.
Feb 09 23:15:06 2020 :: New connection. Waking up.
Feb 09 23:15:24 2020 :: Duckduckduckduckduck [localhost] new player.
*** buffer overflow detected ***: /home/rescator/test/tbamud/bin/circle terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7ffff784c7e5]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x5c)[0x7ffff78ee15c]
/lib/x86_64-linux-gnu/libc.so.6(+0x117160)[0x7ffff78ec160]
/lib/x86_64-linux-gnu/libc.so.6(+0x1164b2)[0x7ffff78eb4b2]
/home/rescator/test/tbamud/bin/circle[0x4408d3]
/home/rescator/test/tbamud/bin/circle[0x4a0e76]
/home/rescator/test/tbamud/bin/circle[0x456127]
/home/rescator/test/tbamud/bin/circle[0x402ea0]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7ffff77f5830]
/home/rescator/test/tbamud/bin/circle[0x403389]
======= Memory map: ========
00400000-00561000 r-xp 00000000 08:01 6033375 /home/rescator/test/tbamud/bin/circle
00761000-00762000 r--p 00161000 08:01 6033375 /home/rescator/test/tbamud/bin/circle
00762000-00765000 rw-p 00162000 08:01 6033375 /home/rescator/test/tbamud/bin/circle
00765000-01ba3000 rw-p 00000000 00:00 0 [heap]
7ffff6f67000-7ffff6f7d000 r-xp 00000000 08:01 5640757 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff6f7d000-7ffff717c000 ---p 00016000 08:01 5640757 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff717c000-7ffff717d000 rw-p 00015000 08:01 5640757 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff717d000-7ffff7188000 r-xp 00000000 08:01 5636310 /lib/x86_64-linux-gnu/libnss_files-2.23.so
7ffff7188000-7ffff7387000 ---p 0000b000 08:01 5636310 /lib/x86_64-linux-gnu/libnss_files-2.23.so
7ffff7387000-7ffff7388000 r--p 0000a000 08:01 5636310 /lib/x86_64-linux-gnu/libnss_files-2.23.so
7ffff7388000-7ffff7389000 rw-p 0000b000 08:01 5636310 /lib/x86_64-linux-gnu/libnss_files-2.23.so
7ffff7389000-7ffff77d5000 rw-p 00000000 00:00 0
7ffff77d5000-7ffff7995000 r-xp 00000000 08:01 5636313 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7995000-7ffff7b95000 ---p 001c0000 08:01 5636313 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7b95000-7ffff7b99000 r--p 001c0000 08:01 5636313 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7b99000-7ffff7b9b000 rw-p 001c4000 08:01 5636313 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7b9b000-7ffff7b9f000 rw-p 00000000 00:00 0
7ffff7b9f000-7ffff7ba8000 r-xp 00000000 08:01 5636307 /lib/x86_64-linux-gnu/libcrypt-2.23.so
7ffff7ba8000-7ffff7da7000 ---p 00009000 08:01 5636307 /lib/x86_64-linux-gnu/libcrypt-2.23.so
7ffff7da7000-7ffff7da8000 r--p 00008000 08:01 5636307 /lib/x86_64-linux-gnu/libcrypt-2.23.so
7ffff7da8000-7ffff7da9000 rw-p 00009000 08:01 5636307 /lib/x86_64-linux-gnu/libcrypt-2.23.so
7ffff7da9000-7ffff7dd7000 rw-p 00000000 00:00 0
7ffff7dd7000-7ffff7dfd000 r-xp 00000000 08:01 5636299 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7e97000-7ffff7fd9000 rw-p 00000000 00:00 0
7ffff7ff7000-7ffff7ff8000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00025000 08:01 5636299 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffd000-7ffff7ffe000 rw-p 00026000 08:01 5636299 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffbe000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

Program received signal SIGABRT, Aborted.
0x00007ffff780a428 in __GI_raise (sig=sig@entry=6)
at ../sysdeps/unix/sysv/linux/raise.c:54
54 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 0x00007ffff780a428 in __GI_raise (sig=sig@entry=6)
at ../sysdeps/unix/sysv/linux/raise.c:54
#1 0x00007ffff780c02a in __GI_abort () at abort.c:89
#2 0x00007ffff784c7ea in __libc_message (do_abort=do_abort@entry=2,
fmt=fmt@entry=0x7ffff796449f "*** %s ***: %s terminated\n")
at ../sysdeps/posix/libc_fatal.c:175
#3 0x00007ffff78ee15c in __GI___fortify_fail (msg=<optimized out>,
msg@entry=0x7ffff7964430 "buffer overflow detected") at fortify_fail.c:37
#4 0x00007ffff78ec160 in __GI___chk_fail () at chk_fail.c:28
#5 0x00007ffff78eb4b2 in __strcpy_chk (dest=0x1b8b9f4 "",
src=0x153a850 "Duckduckduckduckduck", destlen=20) at strcpy_chk.c:30
#6 0x00000000004408d3 in strcpy (__src=0x153a850 "Duckduckduckduckduck",
__dest=0x1b8b9f4 "") at /usr/include/x86_64-linux-gnu/bits/string3.h:110
#7 AddRecentPlayer (chname=0x153a850 "Duckduckduckduckduck",
chhost=chhost@entry=0x1b85db4 "localhost", newplr=newplr@entry=1 '\001',
cpyplr=cpyplr@entry=0 '\000') at act.wizard.c:4974
#8 0x00000000004a0e76 in nanny (d=d@entry=0x1b85db0,
arg=arg@entry=0x7fffffffd750 "m") at interpreter.c:1637
#9 0x0000000000456127 in game_loop (local_mother_desc=3) at comm.c:898
#10 0x0000000000402ea0 in init_game (local_port=<optimized out>) at comm.c:541
#11 main (argc=<optimized out>, argv=<optimized out>) at comm.c:352
(gdb) up
#1 0x00007ffff780c02a in __GI_abort () at abort.c:89
89 abort.c: No such file or directory.
(gdb) up
#2 0x00007ffff784c7ea in __libc_message (do_abort=do_abort@entry=2,
fmt=fmt@entry=0x7ffff796449f "*** %s ***: %s terminated\n")
at ../sysdeps/posix/libc_fatal.c:175
175 ../sysdeps/posix/libc_fatal.c: No such file or directory.
(gdb) up
#3 0x00007ffff78ee15c in __GI___fortify_fail (msg=<optimized out>,
msg@entry=0x7ffff7964430 "buffer overflow detected") at fortify_fail.c:37
37 fortify_fail.c: No such file or directory.
(gdb) up
#4 0x00007ffff78ec160 in __GI___chk_fail () at chk_fail.c:28
28 chk_fail.c: No such file or directory.
(gdb) up
#5 0x00007ffff78eb4b2 in __strcpy_chk (dest=0x1b8b9f4 "",
src=0x153a850 "Duckduckduckduckduck", destlen=20) at strcpy_chk.c:30
30 strcpy_chk.c: No such file or directory.
(gdb) up
#6 0x00000000004408d3 in strcpy (__src=0x153a850 "Duckduckduckduckduck",
__dest=0x1b8b9f4 "") at /usr/include/x86_64-linux-gnu/bits/string3.h:110
110 return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
(gdb) up
#7 AddRecentPlayer (chname=0x153a850 "Duckduckduckduckduck",
chhost=chhost@entry=0x1b85db4 "localhost", newplr=newplr@entry=1 '\001',
cpyplr=cpyplr@entry=0 '\000') at act.wizard.c:4974
4974 strcpy(this->name, chname);
(gdb)

[Client] xterm-256color | [Colors] 256 | [MXP] No | [MSDP] No | [ATCP] No

T B A M U D
2 0 2 0

Based on CircleMUD by Jeremy Elson and DikuMUD by Hans-Henrik Staerfeldt,
Katja Nyboe, Tom Madsen, Michael Seifert, and Sebastian Hammer

By what name do you wish to be known? duckduckduckduckduck
Did I get that right, Duckduckduckduckduck (Y/N)? y
New character.
Give me a password for Duckduckduckduckduck:
Please retype password:
What is your sex (M/F)? m

Select a class:
[C]leric
[T]hief
[W]arrior
[M]agic-user

Class: m


But. like i said:
/* Add player to recent player list */
bool AddRecentPlayer(char *chname, char *chhost, bool newplr, bool cpyplr)
{
  struct recent_player *this;
  time_t ct;
  int max_vnum;

  if (!chname || !*chname) // dropped connection with no name given
       return FALSE;

  ct = time(0);  /* Grab the current time */

  this = create_recent();

  if (!this) return FALSE;

  this->time = ct;
  this->new_player = newplr;
  this->copyover_player = cpyplr;
  strcpy(this->host, chhost);
  strcpy(this->name, chname);
  max_vnum = get_max_recent();
  this->vnum = max_vnum;   /* Possibly should be +1 ? */

  return TRUE;
}

Changing:
/** structure for list of recent players (see 'recent' command) */
struct recent_player
{
   int    vnum;                   /* The ID number for this instance */
   char   name[MAX_NAME_LENGTH];  /* The char name of the player     */
   bool   new_player;             /* Is this a new player?           */
   bool   copyover_player;        /* Is this a player that was on during the last copyover? */
   time_t time;                   /* login time                      */
   char   host[HOST_LENGTH+1];    /* Host IP address                 */
   struct recent_player *next;    /* Pointer to the next instance    */
};

Changing: char name[MAX_NAME_LENGTH]
by: char name[MAX_NAME_LENGTH+1]
fix the issue.

Please Log in or Create an account to join the conversation.

More
6 months 1 day ago #8554 by Castillo

Weird, I just did the same thing on my copy of the mud in exactly the same way and it didn't crash. I successfully went through character generation and logged into the game. 21 characters or more resulted in "Invalid name." Perhaps it's your implementation of strlen()? Maybe strnlen() might be the better option?


Well, if i understand. It's a buffer overflow detected by "LibC" ? That, send SIGABORT to the program?
Maybe, your version of the library is diffrent, and doesn't detect it... and, since it's a small overflow it's doesn't affect the program execution on your system maybe?

Bob

Please Log in or Create an account to join the conversation.

More
6 months 1 day ago #8555 by Krell

Castillo wrote: Maybe, your version of the library is diffrent, and doesn't detect it... and, since it's a small overflow it's doesn't affect the program execution on your system maybe?


Doubt it. OpenBSD's philosophy is that overflows because there's no room for NULL should crash and crash hard. Either the compiler is swapping strlen() for another function, and from my understanding that only occurs when it runs across strncat() or strncpy(), or there's a bug.

Please Log in or Create an account to join the conversation.

More
6 months 1 day ago #8556 by Castillo
I did some tests:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int main()
{
 const int MAX_NAME_LENGTH = 20;
 const char *chname = "duckduckduckduckduck";
 char name [MAX_NAME_LENGTH];

 strcpy(name, chname);
 return 0;
}

gcc test.c
./a.out

that is ok.

BUT, if i compile using the same gcc parameters as TBA mud. i get this:

rescator@rescator-System-Product-Name:~$ gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable test.c
In file included from /usr/include/string.h:635:0,
from test.c:2:
In function ‘strcpy’,
inlined from ‘main’ at test.c:11:2:
/usr/include/x86_64-linux-gnu/bits/string3.h:110:10: warning: call to __builtin___memcpy_chk will always overflow destination buffer
return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
^
rescator@rescator-System-Product-Name:~$ ./a.out
*** buffer overflow detected ***: ./a.out terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f77d3e6a7e5]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x5c)[0x7f77d3f0c15c]
/lib/x86_64-linux-gnu/libc.so.6(+0x117160)[0x7f77d3f0a160]
./a.out[0x4004eb]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f77d3e13830]
./a.out[0x400539]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 5505307 /home/rescator/a.out
00600000-00601000 r--p 00000000 08:01 5505307 /home/rescator/a.out
00601000-00602000 rw-p 00001000 08:01 5505307 /home/rescator/a.out
0066c000-0068d000 rw-p 00000000 00:00 0 [heap]
7f77d3bdd000-7f77d3bf3000 r-xp 00000000 08:01 5640757 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f77d3bf3000-7f77d3df2000 ---p 00016000 08:01 5640757 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f77d3df2000-7f77d3df3000 rw-p 00015000 08:01 5640757 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f77d3df3000-7f77d3fb3000 r-xp 00000000 08:01 5636313 /lib/x86_64-linux-gnu/libc-2.23.so
7f77d3fb3000-7f77d41b3000 ---p 001c0000 08:01 5636313 /lib/x86_64-linux-gnu/libc-2.23.so
7f77d41b3000-7f77d41b7000 r--p 001c0000 08:01 5636313 /lib/x86_64-linux-gnu/libc-2.23.so
7f77d41b7000-7f77d41b9000 rw-p 001c4000 08:01 5636313 /lib/x86_64-linux-gnu/libc-2.23.so
7f77d41b9000-7f77d41bd000 rw-p 00000000 00:00 0
7f77d41bd000-7f77d41e3000 r-xp 00000000 08:01 5636299 /lib/x86_64-linux-gnu/ld-2.23.so
7f77d43c0000-7f77d43c3000 rw-p 00000000 00:00 0
7f77d43e1000-7f77d43e2000 rw-p 00000000 00:00 0
7f77d43e2000-7f77d43e3000 r--p 00025000 08:01 5636299 /lib/x86_64-linux-gnu/ld-2.23.so
7f77d43e3000-7f77d43e4000 rw-p 00026000 08:01 5636299 /lib/x86_64-linux-gnu/ld-2.23.so
7f77d43e4000-7f77d43e5000 rw-p 00000000 00:00 0
7fffb41e9000-7fffb420a000 rw-p 00000000 00:00 0 [stack]
7fffb42bb000-7fffb42bd000 r--p 00000000 00:00 0 [vvar]
7fffb42bd000-7fffb42bf000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted (core dumped)

But, this code:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int main()
{
 const int MAX_NAME_LENGTH = 20;
 const char *chname = "duckduckduckduckduck";
 char name [MAX_NAME_LENGTH+1];

 strcpy(name, chname);
 return 0;
}
With the +1
rescator@rescator-System-Product-Name:~$ gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable test.c
rescator@rescator-System-Product-Name:~$ ./a.out

No warnings, no crash.

Interesting.
Do you understand that?

Please Log in or Create an account to join the conversation.

  • Salty
  • Topic Author
  • Offline
  • Fresh Boarder
  • Fresh Boarder
More
6 months 1 day ago #8557 by Salty
My solution was simply to change the integer comparison in interpreter.c from A > B to A >= B as follows:
strlen(tmp_name) > MAX_NAME_LENGTH
to
strlen(tmp_name) >= MAX_NAME_LENGTH

If I remember my first year CS classes correctly, the array of type char is zero indexed with a null char terminator.

With MAX_ARRAY+1, we're doing a simple A > B integer comparison.
With MAX_ARRAY, we're doing a simple A >= B integer comparison.
Isn't the effect essentially the same?

Some instances of [MAX_NAME_LENGTH +1] exist in the code already such as:
github.com/tbamud/tbamud/blob/7f0acefcb4...rc/spec_procs.c#L583
github.com/tbamud/tbamud/blob/7f0acefcb4...7ea/src/house.c#L295

Yet there are other instances of [MAX_NAME_LENGTH] in some admin functions such as:
github.com/tbamud/tbamud/blob/7f0acefcb4...c/act.wizard.c#L4638

But most interestingly is the implementation of [MAX_NAME_LENGTH] in ban.c
github.com/tbamud/tbamud/blob/7f0acefcb4...f007ea/src/ban.c#L41

In ban.c the author uses strncpy() vs strcpy() to only copy n=MAX_NAME_LENGTH characters to the string which is size MAX_NAME_LENGTH+1.

So I guess what I'm getting at is this: What is the BEST, most portable, solution?
The following user(s) said Thank You: thomas

Please Log in or Create an account to join the conversation.

More
6 months 1 day ago #8558 by Castillo

With MAX_ARRAY+1, we're doing a simple A > B integer comparison.
With MAX_ARRAY, we're doing a simple A >= B integer comparison.
Isn't the effect essentially the same?


The difference with >= will let you register 19 chars name instead of 20.
While MAX_ARRAY+1 seems more logical with the rest of the code.

(see structs.h) all the +1 ARRAY

Both solution fix the crash, and at the end the developper of TBA mud will make their choice.

Meanwhile, you fixed your crash.
The following user(s) said Thank You: Salty

Please Log in or Create an account to join the conversation.

  • Salty
  • Topic Author
  • Offline
  • Fresh Boarder
  • Fresh Boarder
More
6 months 1 day ago #8559 by Salty

The difference with >= will let you register 19 chars name instead of 20.
While MAX_ARRAY+1 seems more logical with the rest of the code.


Ah yes, because I still need room for the null terminator.

Thanks.

Please Log in or Create an account to join the conversation.

More
6 months 1 day ago - 6 months 1 day ago #8560 by Krell

Castillo wrote: I did some tests:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int main()
{
 const int MAX_NAME_LENGTH = 20;
 const char *chname = "duckduckduckduckduck";
 char name [MAX_NAME_LENGTH];

 strcpy(name, chname);
 return 0;
}


Okay, this is interesting. I copied your code into a text editor in my terminal, compiled the first way, tested, deleted the a.out, recompiled the second way and had no difference!

I then implemented the following code, everything the same, but added strlen() and some logic to check for overflow.
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int main()
{
    const int MAX_NAME_LENGTH = 20; 
    const char *chname = "duckduckduckduckduck";
    char name [MAX_NAME_LENGTH];
    
    strcpy(name, chname);
    if (strlen(name) > MAX_NAME_LENGTH)
        puts("Buffer overflow!");

    return 0;
}

Again, no differences during compile or running the code.


So either the OpenBSD compiler is doing something ruleswiae under the hood to strcpy() and strlen(), which I doubt, or there's an issue with the new compiler. I'll update my system to see if there's any changes if I recompile those codes. If not I might be asking the OpenBSD devs to kindly explain what's happening.

Addendum:

Just attempted the above steps in the refactored code but with strlen(chname) instead just in case strcpy() might have been cleaning up the buffer somehow. Again, same results.
Last edit: 6 months 1 day ago by Krell.

Please Log in or Create an account to join the conversation.

More
6 months 1 day ago #8563 by thomas
I think the +1 fix is a hack. It would have to be done everywhere we allocate a buffer for a name.
Instead, we must limit to 19 chars, using <= instead of <. That is consistent with the buffer size.
The following user(s) said Thank You: Salty

Please Log in or Create an account to join the conversation.

More
6 months 1 day ago #8564 by Castillo
#define MAX_NAME_LENGTH       20     /**< Max PC/NPC name length */
#define MAX_PWD_LENGTH        30     /**< Max PC password length */

At 31 chars, a password is illegal. 30 chars password is accepted. It's really the MAX_PWD_LENGTH

If the name is restricted to 19, shouldn't MAX_NAME_LENGTH renamed somethings like NAME_BUFSIZE?
That way we know 20 is 19 chars +including \0 ?

Or, is there any reason the particuliar buffer that crash. Couldn't be a pointer?
and, instead of using strcpy, use strdup?

Just some thinking...

Please Log in or Create an account to join the conversation.

  • Salty
  • Topic Author
  • Offline
  • Fresh Boarder
  • Fresh Boarder
More
6 months 1 day ago #8565 by Salty

If the name is restricted to 19, shouldn't MAX_NAME_LENGTH renamed somethings like NAME_BUFSIZE?
That way we know 20 is 19 chars +including \0 ?

Or, is there any reason the particuliar buffer that crash. Couldn't be a pointer?
and, instead of using strcpy, use strdup?


Strnlen() vs strlen()

Probably just better to use strnlen() with n=MAX_NAME_LENGTH instead of strlen()? This way we are guaranteed to get our null byte.

Please Log in or Create an account to join the conversation.

More
6 months 11 hours ago - 6 months 10 hours ago #8566 by Krell

Salty wrote:

If the name is restricted to 19, shouldn't MAX_NAME_LENGTH renamed somethings like NAME_BUFSIZE?
That way we know 20 is 19 chars +including \0 ?
<snipped>


<snipped>

Probably just better to use strnlen() with n=MAX_NAME_LENGTH instead of strlen()? This way we are guaranteed to get our null byte.


I guess it comes down to whether null is added or not. If the buffer holding the string is too full to take a terminating NUL then that can cause instability later on when that string needs to be parsed, is that right? While I'm personally leaning towards strnlen(), I think using strlen() and >= or MAX_NAME_LENGTH + 1 should functionally do the same as strlen() counts up to the terminating NUL.

Addendum: I don't think strnlen() guarantees a terminating NUL as, according to the man pages,

The strnlen() function computes the length of the string s, up to maxlen
characters. The strnlen() function will never attempt to address more
than maxlen characters, making it suitable for use with character arrays
that are not guaranteed to be NUL-terminated.


Which would be useful for checking for such strings and adding null to the end to fix them, I guess.
Last edit: 6 months 10 hours ago by Krell.

Please Log in or Create an account to join the conversation.

More
5 months 4 weeks ago #8567 by Castillo

I guess it comes down to whether null is added or not. If the buffer holding the string is too full to take a terminating NUL then that can cause instability later on when that string needs to be parsed, is that right? While I'm personally leaning towards strnlen(), I think using strlen() and >= or MAX_NAME_LENGTH + 1 should functionally do the same as strlen() counts up to the terminating NUL.

Agreed.

I think the +1 fix is a hack. It would have to be done everywhere we allocate a buffer for a name.
Instead, we must limit to 19 chars, using <= instead of <. That is consistent with the buffer size.

I just wanted to explain why i choosed +1 instead of >=.
I don't mind loosing 1 char. I understand why you don't like it.

What bother me is confusion if sometimes
MAX_SOMETHING1_LENGTH = maxlen + \0
(e.g MAX_PWD_LENGTH = 30 means 30 chars + \0)

and sometimes

MAX_SOMETHING2_LENGTH = maxlen - 1 + \0
(e.g MAX_NAME_LENGTH = 20 means 19 chars +\0)

Bob

Please Log in or Create an account to join the conversation.

More
5 months 2 weeks ago - 5 months 2 weeks ago #8574 by doggo
The issue is that a char * is being casually converted to a char array when it is passed to strcpy.

Having absolutely nothing to do with the gcc flags that tba-2020 uses, the following code (which is an example based on the test that Castillo did above) ought to crash!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
 /* creates a variable chname, which is a pointer
 * to a character, and room for 6 characters (when 
 * the NULL terminator is accounted for) is reserved */
 char *chname = "doggo";

 /* creates a character array which has room for 5 characters */
 char name[5];

 /* will crash, because 6 characters are being 
  * written to an array which only has room for 5 */
 strcpy(name, chname);
 return 0;
}
The fact that you didn't have issues before incorporating the compiler flags
-g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable
is actually the surprising part. It should crash because it's trying to modify memory it doesn't have access to.

To respond to Thomas' thoughts:

I think the +1 fix is a hack. It would have to be done everywhere we allocate a buffer for a name.
Instead, we must limit to 19 chars, using <= instead of <. That is consistent with the buffer size.

This is true, and is to be expected! It's no less weird to implement
#define MAX_NAME_LENGTH  20
and then insist that names be no more than 19 characters long.

The solution suggested by Castillo:
/** structure for list of recent players (see 'recent' command) */
struct recent_player
{
   int    vnum;                   /* The ID number for this instance */
-  char   name[MAX_NAME_LENGTH];  /* The char name of the player     */
+  char   name[MAX_NAME_LENGTH + 1];  /* The char name of the player */
   bool   new_player;             /* Is this a new player?           */
   bool   copyover_player;        /* Is this a player that was on during the last copyover? */
   time_t time;                   /* login time                      */
   char   host[HOST_LENGTH+1];    /* Host IP address                 */
   struct recent_player *next;    /* Pointer to the next instance    */
};
is not a hack. In fact it is the natural choice here.
Last edit: 5 months 2 weeks ago by doggo. Reason: formatting

Please Log in or Create an account to join the conversation.

Time to create page: 0.236 seconds