This is patch20 to PennMUSH 1.7.7. After applying this patch, you will have version 1.7.7p20 To apply this patch, save it to a file in your top-level MUSH directory, and do the following: patch -p1 < 1.7.7-patch20 make install If you use GNU patch 2.2, you probably want the above to be 'patch -b -p1', not just 'patch -p1'. Unix (or cygwin) users need not worry about failed hunks in src/switchinc.c, hdrs/switches.h, hdrs/cmds.h, or hdrs/funs.h. These files are automatically rebuilt on compile. On the off chance they appear not to be, simply rm them and re-run make. Then @shutdown and restart your MUSH. - Alan/Javelin In this patch: Major Changes: * minimal.db is no more. If you start up the server and there's no db to be found, it creates a new minimal database in memory on the fly. Feel free to delete your coopy of minimal.db. [SW] (In related news, the default OSUCC on #0 in minimal.db is gone. Suggested by Cheetah@M*U*S*H. So much for the mists.) Minor Changes: * SSL connections are now ended before the dump when rebooting, but their descriptor information sticks around to ensure that their @adisconnect is run after the reboot. Based on suggestions by Vadiv@M*U*S*H and [TAP]. * When _DEBUG is defined in a win32 build, don't copy pennmush.exe to pennmush_run.exe. Makes debugging easier. Patch by Luke@M*U*S*H. * In pueblo mode, no longer clear past images after each room look. Patch by Konstantine Shirow. * In pueblo mode, we no longer render ansi attributes or colors with HTML tags; we assume the client will correctly handle them as ansi intermixed with Pueblo. This solves a variety of problems. Based on a discussion with Konstantine Shirow. * When matching $commands and ^listens, insure that a matching attribute exists before testing locks. This may break some strange locks using %c, but hopefully won't. Suggested by Cheetah@M*U*S*H. * The @scan command temporarily sets %c to the command to be scanned (without "@scan" prefixed) so that it can detect commands that use %c-matching. Based on ideas from Cheetah and Walker@M*U*S*H. * Added support for Pueblo's md5 checksum. We track it on each descriptor, though we don't do anything with it currently. * Speed-up to fun_merge. Patch by Walker@M*U*S*H. * Internal cleanup of flags in channel_broadcast. * Wizards may @name themselves to names forbidden in names.cnf. Patch by LeeLaLimaLLama@M*U*S*H. * We are now forgiving of stupid non-RFC-compliant telnet clients that send CR only even when they claim to be sending CRLF (Read: MS Windows XP telnet). MS bug reported first by Intrevis@M*U*S*H. * Misleading restrict_command on @clone removed from restrict.cnf, as @dig/@open/@create permissions already control @clone. Suggested by Philip Mak. Functions: * lstats() and quota() now allow objects to see stats/quota on other objects they control (e.g., on their owners, perhaps). Suggested by Philip Mak. * hastype() can now test for type GARBAGE. Suggested by Tanaku@M*U*S*H. Commands: * The new ']' command prefix causes the rest of the command-line not to be evaluated by the expression parser. Try: ]think [add(1,1)] Inspired by Elendor. * @hook/ignore. [mux] * @hook/override [Rhost, though they don't call it that] Attributes: * @debugforwardlist forwards DEBUG output to dbrefs on the list. Suggested by Balerion@M*U*S*H. Tests: * A new test harness for developing regression test suites in perl for PennMUSH is now included; few test suites are. If you can figure out how to use this, write some tests for us! (If you can't, don't ask about it, please :) Locks: * @lock/interact can prevent other players from transmitting any normal sound to you (that is, you won't hear them speak, pose, emit, etc., like gagging them in a client). It doesn't control page (use @lock/page) or @mail (use @lock/mail). You still hear 'presence' messages (connects/disconnects/arrivals/leaves) so you can have a sense of who can hear you but you can't hear. Patch by Philip Mak. Fixes: * Configure script no longer keeps adding -lssl -lcrypto over and over to the Makefile. Report by Sholevi@M*U*S*H. * Portability fixes for compiling with MSVC5 by Luke@M*U*S*H. * The behavior of spaces inside parentheses that aren't part of a function has been improved. Report by Jason Newquist. [TAP] * txt/*.html files were being improperly escaped before being sent to Pueblo connections. Report by Konstantine Shirow. * mushdb.h includes flags.h, as it relies on constants from there. Suggested by Philip Mak. * Better error reporting on some failure messages in chunk allocator. Patch by Philip Mak. * @config/set with an invalid option now returns an error. Report by Sholevi@M*U*S*H. * Fix to interaction checking in notify_anything that could result in the wrong check being performed. Report by Philip Mak. * Help fixes by LeeLaLimaLLama@M*U*S*H, Sunny@M*U*S*H, Sketch@M*U*S*H. Prereq: 1.7.7p19 *** 1_7_7.561/Patchlevel Wed, 20 Aug 2003 01:05:31 -0500 dunemush (pennmush/5_Patchlevel 1.17.1.11.1.21 600) --- 1_7_7.623(w)/Patchlevel Thu, 04 Sep 2003 17:35:47 -0500 dunemush (pennmush/5_Patchlevel 1.17.1.11.1.22 600) *************** *** 1,2 **** Do not edit this file. It is maintained by the official PennMUSH patches. ! This is PennMUSH 1.7.7p19 --- 1,2 ---- Do not edit this file. It is maintained by the official PennMUSH patches. ! This is PennMUSH 1.7.7p20 *** 1_7_7.561/CHANGES.177 Wed, 20 Aug 2003 01:05:31 -0500 dunemush (pennmush/g/23_CHANGES 1.48.1.135 600) --- 1_7_7.623(w)/CHANGES.177 Fri, 05 Sep 2003 20:59:03 -0500 dunemush (pennmush/g/23_CHANGES 1.48.1.165 600) *************** *** 18,23 **** --- 18,109 ---- ========================================================================== + Version 1.7.7 patchlevel 20 September 4, 2003 + + Major Changes: + * minimal.db is no more. If you start up the server and there's no + db to be found, it creates a new minimal database in memory + on the fly. Feel free to delete your coopy of minimal.db. [SW] + (In related news, the default OSUCC on #0 in minimal.db is gone. + Suggested by Cheetah@M*U*S*H. So much for the mists.) + Minor Changes: + * SSL connections are now ended before the dump when rebooting, + but their descriptor information sticks around to ensure that + their @adisconnect is run after the reboot. Based on suggestions + by Vadiv@M*U*S*H and [TAP]. + * When _DEBUG is defined in a win32 build, don't copy pennmush.exe + to pennmush_run.exe. Makes debugging easier. Patch by Luke@M*U*S*H. + * In pueblo mode, no longer clear past images after each room look. + Patch by Konstantine Shirow. + * In pueblo mode, we no longer render ansi attributes or colors with + HTML tags; we assume the client will correctly handle them as ansi + intermixed with Pueblo. This solves a variety of problems. + Based on a discussion with Konstantine Shirow. + * When matching $commands and ^listens, insure that a matching attribute + exists before testing locks. This may break some strange locks using + %c, but hopefully won't. Suggested by Cheetah@M*U*S*H. + * The @scan command temporarily sets %c to the command to be scanned + (without "@scan" prefixed) so that it can detect commands that use + %c-matching. Based on ideas from Cheetah and Walker@M*U*S*H. + * Added support for Pueblo's md5 checksum. We track it on each + descriptor, though we don't do anything with it currently. + * Speed-up to fun_merge. Patch by Walker@M*U*S*H. + * Internal cleanup of flags in channel_broadcast. + * Wizards may @name themselves to names forbidden in names.cnf. + Patch by LeeLaLimaLLama@M*U*S*H. + * We are now forgiving of stupid non-RFC-compliant telnet clients + that send CR only even when they claim to be sending CRLF + (Read: MS Windows XP telnet). MS bug reported first by + Intrevis@M*U*S*H. + * Misleading restrict_command on @clone removed from restrict.cnf, + as @dig/@open/@create permissions already control @clone. + Suggested by Philip Mak. + Functions: + * lstats() and quota() now allow objects to see stats/quota on other + objects they control (e.g., on their owners, perhaps). Suggested + by Philip Mak. + * hastype() can now test for type GARBAGE. Suggested by Tanaku@M*U*S*H. + Commands: + * The new ']' command prefix causes the rest of the command-line + not to be evaluated by the expression parser. Try: ]think [add(1,1)] + Inspired by Elendor. + * @hook/ignore. [mux] + * @hook/override [Rhost, though they don't call it that] + Attributes: + * @debugforwardlist forwards DEBUG output to dbrefs on the list. + Suggested by Balerion@M*U*S*H. + Tests: + * A new test harness for developing regression test suites in perl + for PennMUSH is now included; few test suites are. If you can figure + out how to use this, write some tests for us! (If you can't, don't + ask about it, please :) + Locks: + * @lock/interact can prevent other players from transmitting any + normal sound to you (that is, you won't hear them speak, pose, + emit, etc., like gagging them in a client). It doesn't control + page (use @lock/page) or @mail (use @lock/mail). You still + hear 'presence' messages (connects/disconnects/arrivals/leaves) + so you can have a sense of who can hear you but you can't hear. + Patch by Philip Mak. + Fixes: + * Configure script no longer keeps adding -lssl -lcrypto over and + over to the Makefile. Report by Sholevi@M*U*S*H. + * Portability fixes for compiling with MSVC5 by Luke@M*U*S*H. + * The behavior of spaces inside parentheses that aren't part of a + function has been improved. Report by Jason Newquist. [TAP] + * txt/*.html files were being improperly escaped before being + sent to Pueblo connections. Report by Konstantine Shirow. + * mushdb.h includes flags.h, as it relies on constants from there. + Suggested by Philip Mak. + * Better error reporting on some failure messages in chunk allocator. + Patch by Philip Mak. + * @config/set with an invalid option now returns an error. + Report by Sholevi@M*U*S*H. + * Fix to interaction checking in notify_anything that could result + in the wrong check being performed. Report by Philip Mak. + * Help fixes by LeeLaLimaLLama@M*U*S*H, Sunny@M*U*S*H, Sketch@M*U*S*H. + + Version 1.7.7 patchlevel 19 August 19, 2003 Fixes: *** 1_7_7.561/game/txt/hlp/pennfunc.hlp Mon, 11 Aug 2003 16:30:36 -0500 dunemush (pennmush/16_pennfunc.h 1.2.1.50.1.1.1.1.1.2.1.7.1.8.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.9.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.7 600) --- 1_7_7.623(w)/game/txt/hlp/pennfunc.hlp Fri, 05 Sep 2003 20:58:18 -0500 dunemush (pennmush/16_pennfunc.h 1.2.1.50.1.1.1.1.1.2.1.7.1.8.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.9.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.10 600) *************** *** 65,73 **** aposs() default() edefault() eval() filter() filterbool() fold() foreach() get() grep() ! grepi() lattr() obj() poss() regrep() ! regrepi() subj() udefault() ufun() uldefault() ! ulocal() v-function xget() zfun() See also: ATTRIBUTES, NON-STANDARD ATTRIBUTES & Bitwise functions --- 65,73 ---- aposs() default() edefault() eval() filter() filterbool() fold() foreach() get() grep() ! grepi() lattr() nattr() obj() poss() ! regrep() regrepi() subj() udefault() ufun() ! uldefault() ulocal() v-function xget() zfun() See also: ATTRIBUTES, NON-STANDARD ATTRIBUTES & Bitwise functions *************** *** 609,617 **** & CLOCK() clock([/][, ]) ! With one argument, returns the value of a lock on a channel. ! If no locktype is given, "JOIN" is assumed. ! With two arguments, sets the lock. See also: @clock & CLONE() --- 609,619 ---- & CLOCK() clock([/][, ]) ! With one argument, returns the value of a lock on a channel, if you ! own the channel or are See_All. If no locktype is given, "JOIN" ! is assumed. ! With two arguments, sets the lock if you would be able to do so via ! @clock. See also: @clock & CLONE() *************** *** 1431,1438 **** hastype(, ) Returns 1 if the object is of the named type, otherwise 0. ! Valid types are: ROOM, EXIT, PLAYER, THING. ! If an invalid type is given, #-1 is returned. & HIDDEN() hidden() --- 1433,1440 ---- hastype(, ) Returns 1 if the object is of the named type, otherwise 0. ! Valid types are: ROOM, EXIT, PLAYER, THING, GARBAGE. ! If an invalid type is given, #-1 NO SUCH TYPE is returned. & HIDDEN() hidden() *************** *** 1690,1695 **** --- 1692,1698 ---- If a wildcarded attribute pattern is provided, only attribute names matching that pattern will be returned. + See also: nattr() & NATTR() & ATTRCNT() nattr() *************** *** 3164,3171 **** & STARTTIME() Function: starttime() ! Returns a string which is the time the MUSH first started up. The time ! is in the same format as the TIME() function returns. Example: > say starttime() --- 3167,3175 ---- & STARTTIME() Function: starttime() ! Returns a string containing the time the MUSH first started up (not ! including @shutdown/reboots). The time is in the same format that the ! TIME() function returns. Example: > say starttime() *** 1_7_7.561/game/txt/hlp/pennflag.hlp Thu, 17 Jul 2003 15:28:00 -0500 dunemush (pennmush/17_pennflag.h 1.1.1.1.1.2.1.1.1.2.1.1.1.2.1.1.2.1.2.1.1.1.1.2.1.4.1.2.2.7 600) --- 1_7_7.623(w)/game/txt/hlp/pennflag.hlp Mon, 01 Sep 2003 23:39:21 -0500 dunemush (pennmush/17_pennflag.h 1.1.1.1.1.2.1.1.1.2.1.1.1.2.1.1.2.1.2.1.1.1.1.2.1.4.1.2.2.8 600) *************** *** 199,206 **** The DEBUG flag is used for debugging MUSHcode. It is meant to be used in conjunction with the VERBOSE flag. If an object is set DEBUG, all ! parser evaluation results will be shown to the object's owner, in the ! format: #dbref! : #dbref! recursive evaluation of functions in string --- 199,206 ---- The DEBUG flag is used for debugging MUSHcode. It is meant to be used in conjunction with the VERBOSE flag. If an object is set DEBUG, all ! parser evaluation results will be shown to the object's owner and to ! any dbrefs in the object's DEBUGFORWARDLIST, in the format: #dbref! : #dbref! recursive evaluation of functions in string *************** *** 212,221 **** messages evaluating specific parts of an expression. This enables you to pinpoint exactly which evaluation is going wrong. ! Objects run under this flag are computationally expensive. ! Avoid leaving it set on objects. It can also generate huge amounts of ! spam from the output. ! See "help DEBUG2" for more. & DEBUG2 --- 212,221 ---- messages evaluating specific parts of an expression. This enables you to pinpoint exactly which evaluation is going wrong. ! Objects run under this flag are computationally expensive. Avoid ! leaving it set on objects. It can also generate huge amounts of spam ! from the output. ! See "help DEBUG2" for more. & DEBUG2 *** 1_7_7.561/game/txt/hlp/penncmd.hlp Mon, 11 Aug 2003 13:09:23 -0500 dunemush (pennmush/18_penncmd.hl 1.2.1.1.1.47.1.1.1.1.1.3.1.4.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.10.1.1.1.1.1.1.1.1.1.6 600) --- 1_7_7.623(w)/game/txt/hlp/penncmd.hlp Tue, 02 Sep 2003 10:07:16 -0500 dunemush (pennmush/18_penncmd.hl 1.2.1.1.1.47.1.1.1.1.1.3.1.4.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.10.1.1.1.1.1.1.1.1.1.11 600) *************** *** 8,14 **** pose QUIT read rules say score slay take teach think unfollow use whisper WHO with ! " : ; + In addition to these, there are several types of '@' commands. @-commands are usually commands which have permanent effects on the MUSH (such as --- 8,14 ---- pose QUIT read rules say score slay take teach think unfollow use whisper WHO with ! " : ; + ] In addition to these, there are several types of '@' commands. @-commands are usually commands which have permanent effects on the MUSH (such as *************** *** 73,78 **** --- 73,98 ---- @shutdown @sitelock @squota @uptime @wall @wizmotd @wizwall cd ch cv + & ] + The "]" command-prefix instructs the MUSH that the rest of the command + input that follows should not be evaluated. Here's an example: + + > say [add(1,1)] + You say, "2" + + > say \[add(1,1)\] + You say, "[add(1,1)]" + + > ]say [add(1,1)] + You say, "[add(1,1)]" + + > ]"[add(1,1)] + You say, "[add(1,1)]" + + This can be used to pass unevaluated MUSHcode to softcoded commands + without having to escape every special character, or to help objects + set attributes to contain unevaluated code. + & @@ The "@@" command is a special kind of command; it signals the start *************** *** 1509,1522 **** @hook tells the command parser to evaluate given attributes at certain points in command evaluation. The possible points, indicated by the proper switch: ! @hook/before: The attribute is evaluated before the command itself is run. ! @hook/after: The attribute is evaluated after the command is run. In all cases, %# is the dbref of the object doing the command, and all ! hooks share the same set of q-registers. The results of the evaluated ! attribute is thrown away like it was wrapped in a call of null(). Also, ! in cases where a command and function do the same thing (e.g., @pemit and ! pemit()), only the command gets the hooks. Leaving out the object and attribute clears an existing hook. Wizards can see existing hooks with @command. --- 1529,1553 ---- @hook tells the command parser to evaluate given attributes at certain points in command evaluation. The possible points, indicated by the proper switch: ! @hook/ignore: The attribute is evaluated before the built-in command is run. ! If it returns a false value, the command is skipped ! (the input is still matched against softcoded commands) ! @hook/override: The object/attribute is matched for a $command, ! and if it matches, it is run instead of the built-in command, ! but with the precedence of the built-in command (thus ! overriding not only the built-in command but any local ! $commands that might match). If the match fails, normal ! built-in command processing continues. Note that all locks ! and flags on the object (HALT, etc.) still apply. ! @hook/before: The attribute is evaluated before the built-in command is run. ! @hook/after: The attribute is evaluated after the built-in command is run. In all cases, %# is the dbref of the object doing the command, and all ! hooks share the same set of q-registers. With /before and /after, ! the results of the evaluated attribute is thrown away like it was ! wrapped in a call of null(). Also, in cases where a command and function ! do the same thing (e.g., @pemit and pemit()), only the command gets ! the hooks. Leaving out the object and attribute clears an existing hook. Wizards can see existing hooks with @command. *************** *** 1946,1951 **** --- 1977,1983 ---- @lock/control Who can control this object (only if set) @lock/dropto Who can trigger this container's drop-to. @lock/destroy Who can destroy this object if it's DESTROY_OK + @lock/interact Who can send sound (say/pose/emit/etc) to this object See also: @lock, @lset, @clock, FAILURE & @lset *************** *** 2628,2633 **** --- 2660,2666 ---- 'help @search2' for more. & @search2 If =EXITS, OBJECTS, ROOMS, or PLAYERS, only objects of that type + will be listed. If =FLAGS or LFLAGS, only objects with the list of flags specified by will be listed. For FLAGS, flags to match *** 1_7_7.561/game/restart Thu, 29 May 2003 11:46:13 -0500 dunemush (pennmush/39_restart 1.1.1.1.1.1.1.2.1.1.1.1.1.2.1.2.2.1.2.2 700) --- 1_7_7.623(w)/game/restart Wed, 03 Sep 2003 22:31:21 -0500 dunemush (pennmush/39_restart 1.1.1.1.1.1.1.2.1.1.1.1.1.2.1.2.2.1.2.2.1.1 700) *************** *** 117,142 **** echo "Using save/$INDB$SUFFIX.old." cp save/$INDB$SUFFIX.old data/$INDB$SUFFIX else ! echo "No save/$INDB$SUFFIX.old found." ! if [ -r data/minimal.db ]; then ! echo "Using data/minimal.db." ! cat data/minimal.db | $COMPRESSOR > data/$INDB$SUFFIX ! else ! if [ -r data/minimal.db.Z ]; then ! echo "Using data/minimal.db.Z." ! zcat data/minimal.db.Z | $COMPRESSOR > data/$INDB$SUFFIX ! else ! echo "No minimal.db.Z found." ! if [ -r data/minimal.db.gz ]; then ! echo "Using data/minimal.db.gz." ! gzip -d -c data/minimal.db.gz | $COMPRESSOR > data/$INDB$SUFFIX ! else ! echo "No minimal.db.gz found." ! echo "I can't find any usable database." ! fi ! fi ! fi ! fi fi fi --- 117,124 ---- echo "Using save/$INDB$SUFFIX.old." cp save/$INDB$SUFFIX.old data/$INDB$SUFFIX else ! echo "No database found. Mush will start with a minimal world." ! fi fi fi *** 1_7_7.561/src/SWITCHES Wed, 28 May 2003 10:06:29 -0500 dunemush (pennmush/b/22_SWITCHES 1.12.1.3.1.6 600) --- 1_7_7.623(w)/src/SWITCHES Wed, 10 Sep 2003 14:47:30 -0500 dunemush (pennmush/b/22_SWITCHES 1.12.1.3.1.7 600) *************** *** 54,59 **** --- 54,60 ---- HEADER HERE HIDE + IGNORE ILIST INVENTORY IPRINT *** 1_7_7.561/src/wiz.c Tue, 19 Aug 2003 12:07:25 -0500 dunemush (pennmush/b/23_wiz.c 1.44.1.1.1.1.1.2.1.7.1.1.1.1.1.1.1.1.1.1.1.8.1.2.2.2.1.2.1.1.1.1.1.1.1.2.1.1.1.2.2.16 660) --- 1_7_7.623(w)/src/wiz.c Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/b/23_wiz.c 1.44.1.1.1.1.1.2.1.7.1.1.1.1.1.1.1.1.1.1.1.8.1.2.2.2.1.2.1.1.1.1.1.1.1.2.1.1.1.2.2.17.1.1 660) *************** *** 1686,1692 **** return; } if (!(Do_Quotas(executor) || See_All(executor) ! || (who == executor))) { notify(executor, T("You can't see someone else's quota!")); safe_str("#-1", buff, bp); return; --- 1686,1692 ---- return; } if (!(Do_Quotas(executor) || See_All(executor) ! || controls(executor, who))) { notify(executor, T("You can't see someone else's quota!")); safe_str("#-1", buff, bp); return; *************** *** 2006,2011 **** --- 2006,2014 ---- if (paranoid_checkpt < 1) paranoid_checkpt = 1; } + #ifdef HAS_OPENSSL + close_ssl_connections(); + #endif fork_and_dump(0); #ifndef PROFILING #ifndef WIN32 *************** *** 2015,2023 **** */ ignore_signal(SIGPROF); #endif - #ifdef HAS_OPENSSL - close_ssl_connections(); - #endif #endif dump_reboot_db(); #ifdef INFO_SLAVE --- 2018,2023 ---- *** 1_7_7.561/src/utils.c Tue, 06 May 2003 17:27:48 -0500 dunemush (pennmush/b/27_utils.c 1.30.1.1.1.12 660) --- 1_7_7.623(w)/src/utils.c Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/b/27_utils.c 1.30.1.1.1.14 660) *************** *** 45,50 **** --- 45,51 ---- #include "flags.h" #include "dbdefs.h" #include "attrib.h" + #include "lock.h" #include "confmagic.h" dbref find_entrance(dbref door); *************** *** 579,584 **** --- 580,593 ---- if ((from == Location(to)) || (to == Location(from)) || controls(to, from)) return 1; + /* If it's an audible message, it must pass your Interact_Lock + * (or be from a privileged speaker) + */ + if ((type == INTERACT_HEAR) && !Pemit_All(from) + && !eval_lock(from, to, Interact_Lock)) + return 0; + + lci = local_can_interact_last(from, to, type); if (lci != NOTHING) return lci; *** 1_7_7.561/src/timer.c Mon, 18 Aug 2003 21:28:01 -0500 dunemush (pennmush/b/29_timer.c 1.29.1.7.1.12 660) --- 1_7_7.623(w)/src/timer.c Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/b/29_timer.c 1.29.1.7.1.13 660) *************** *** 301,306 **** --- 301,309 ---- reload_sig_handler(SIGPROF, signal_cpu_limit); } #elif defined(WIN32) + #if _MSC_VER <= 1100 && !defined(UINT_PTR) + #define UINT_PTR UINT + #endif UINT_PTR timer_id; VOID CALLBACK win32_timer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) *** 1_7_7.561/src/switchinc.c Mon, 23 Jun 2003 11:10:04 -0500 dunemush (pennmush/b/32_switchinc. 1.3.1.2.1.6.1.18.1.2.1.2.2.5.1.4.2.4.1.1.1.2.1.5.1.2.1.5.2.1.1.31.3.4.1.5.1.4.1.1.1.1.1.1.1.7 660) --- 1_7_7.623(w)/src/switchinc.c Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/b/32_switchinc. 1.3.1.2.1.6.1.18.1.2.1.2.2.5.1.4.2.4.1.1.1.2.1.5.1.2.1.5.2.1.1.31.3.4.1.5.1.4.1.1.1.1.1.1.1.7.1.1 660) *************** *** 56,61 **** --- 56,62 ---- {"HEADER", SWITCH_HEADER}, {"HERE", SWITCH_HERE}, {"HIDE", SWITCH_HIDE}, + {"IGNORE", SWITCH_IGNORE}, {"ILIST", SWITCH_ILIST}, {"INVENTORY", SWITCH_INVENTORY}, {"IPRINT", SWITCH_IPRINT}, *** 1_7_7.561/src/speech.c Tue, 06 May 2003 17:27:48 -0500 dunemush (pennmush/b/35_speech.c 1.21.1.2.1.3.1.5.1.1.1.7.1.3.1.1.1.8.1.1.1.1.1.1.1.10.1.2.1.13.2.4.1.1.3.1.1.5 660) --- 1_7_7.623(w)/src/speech.c Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/b/35_speech.c 1.21.1.2.1.3.1.5.1.1.1.7.1.3.1.1.1.8.1.1.1.1.1.1.1.10.1.2.1.13.2.4.1.1.3.1.1.5.1.1 660) *************** *** 303,309 **** if (oneloc) { /* Only one room to oemit to. */ ! notify_anything(orator, na_exceptN, pass, ns_esnotify, 0, message); do_audible_stuff(pass[1], &pass[2], pass[0], message); return; } else if (pass[0] == 0) { --- 303,310 ---- if (oneloc) { /* Only one room to oemit to. */ ! notify_anything(orator, na_exceptN, pass, ns_esnotify, NA_INTER_HEAR, ! message); do_audible_stuff(pass[1], &pass[2], pass[0], message); return; } else if (pass[0] == 0) { *************** *** 314,325 **** */ qsort((void *) locs, pass[0], sizeof(locs[0]), i_comp); pass[1] = locs[0]; ! notify_anything(orator, na_exceptN, pass, ns_esnotify, 0, message); do_audible_stuff(pass[1], &pass[2], pass[0], message); for (i = 1; i < pass[0]; i++) { if (locs[i] != locs[i - 1]) { pass[1] = locs[i]; ! notify_anything(orator, na_exceptN, pass, ns_esnotify, 0, message); do_audible_stuff(pass[1], &pass[2], pass[0], message); } } --- 315,328 ---- */ qsort((void *) locs, pass[0], sizeof(locs[0]), i_comp); pass[1] = locs[0]; ! notify_anything(orator, na_exceptN, pass, ns_esnotify, NA_INTER_HEAR, ! message); do_audible_stuff(pass[1], &pass[2], pass[0], message); for (i = 1; i < pass[0]; i++) { if (locs[i] != locs[i - 1]) { pass[1] = locs[i]; ! notify_anything(orator, na_exceptN, pass, ns_esnotify, NA_INTER_HEAR, ! message); do_audible_stuff(pass[1], &pass[2], pass[0], message); } } *************** *** 382,390 **** current = next_in_list(start); who = match_result(player, current, TYPE_PLAYER, MAT_NEAR_THINGS | MAT_CONTAINER); ! if (!GoodObject(who)) { safe_chr(' ', tbuf, &tp); safe_str_space(current, tbuf, &tp); } else { /* A good whisper */ good[gcount++] = who; --- 385,395 ---- current = next_in_list(start); who = match_result(player, current, TYPE_PLAYER, MAT_NEAR_THINGS | MAT_CONTAINER); ! if (!GoodObject(who) || !can_interact(player, who, INTERACT_HEAR)) { safe_chr(' ', tbuf, &tp); safe_str_space(current, tbuf, &tp); + if (GoodObject(who)) + notify_format(player, T("%s can't hear you."), Name(who)); } else { /* A good whisper */ good[gcount++] = who; *************** *** 1120,1130 **** */ if (IsExit(thing)) { ! notify_anything(orator, na_next, &Contents(loc), NULL, 0, tbuf1); } else { pass[0] = Contents(loc); pass[1] = thing; ! notify_anything(orator, na_nextbut, pass, NULL, 0, tbuf1); } } --- 1125,1136 ---- */ if (IsExit(thing)) { ! notify_anything(orator, na_next, &Contents(loc), NULL, NA_INTER_HEAR, ! tbuf1); } else { pass[0] = Contents(loc); pass[1] = thing; ! notify_anything(orator, na_nextbut, pass, NULL, NA_INTER_HEAR, tbuf1); } } *************** *** 1233,1239 **** pass[1] = exc1; pass[2] = exc2; ! notify_anything(orator, na_except2, pass, ns_esnotify, 0, msg); do_audible_stuff(loc, &pass[1], 2, msg); } --- 1239,1245 ---- pass[1] = exc1; pass[2] = exc2; ! notify_anything(orator, na_except2, pass, ns_esnotify, NA_INTER_HEAR, msg); do_audible_stuff(loc, &pass[1], 2, msg); } *************** *** 1271,1277 **** } /* notify everybody */ ! notify_anything(player, na_loc, &loc, ns_esnotify, 0, tbuf1); do_audible_stuff(loc, NULL, 0, tbuf1); } --- 1277,1283 ---- } /* notify everybody */ ! notify_anything(player, na_loc, &loc, ns_esnotify, NA_INTER_HEAR, tbuf1); do_audible_stuff(loc, NULL, 0, tbuf1); } *************** *** 1304,1310 **** rmno = unparse_object(player, room); notify_format(player, T("You remit, \"%s\" in %s"), msg, rmno); } ! notify_anything(player, na_loc, &room, ns_esnotify, 0, msg); do_audible_stuff(room, NULL, 0, msg); } } --- 1310,1316 ---- rmno = unparse_object(player, room); notify_format(player, T("You remit, \"%s\" in %s"), msg, rmno); } ! notify_anything(player, na_loc, &room, ns_esnotify, NA_INTER_HEAR, msg); do_audible_stuff(room, NULL, 0, msg); } } *************** *** 1369,1375 **** } else { if (!silent && (Location(player) != room)) notify_format(player, T("You lemit: \"%s\""), tbuf1); ! notify_anything(player, na_loc, &room, ns_esnotify, 0, tbuf1); } } --- 1375,1381 ---- } else { if (!silent && (Location(player) != room)) notify_format(player, T("You lemit: \"%s\""), tbuf1); ! notify_anything(player, na_loc, &room, ns_esnotify, NA_INTER_HEAR, tbuf1); } } *************** *** 1445,1449 **** pass[2] = zone; pass[3] = player; pass[4] = player; ! notify_anything(player, na_zemit, pass, ns_esnotify, 0, arg2); } --- 1451,1455 ---- pass[2] = zone; pass[3] = player; pass[4] = player; ! notify_anything(player, na_zemit, pass, ns_esnotify, NA_INTER_HEAR, arg2); } *** 1_7_7.561/src/set.c Mon, 11 Aug 2003 14:04:21 -0500 dunemush (pennmush/b/38_set.c 1.26.1.5.1.1.2.1.1.1.1.1.1.11.1.1.1.1.1.1.1.1.1.1.1.1.1.8 660) --- 1_7_7.623(w)/src/set.c Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/b/38_set.c 1.26.1.5.1.1.2.1.1.1.1.1.1.11.1.1.1.1.1.1.1.1.1.1.1.1.1.9 660) *************** *** 122,128 **** } } if (strcasecmp(newname, Name(thing)) ! && !ok_player_name(newname)) { /* strcasecmp allows changing foo to Foo, etc. */ notify(player, T("You can't give a player that name.")); return; --- 122,128 ---- } } if (strcasecmp(newname, Name(thing)) ! && !ok_player_name(newname, thing)) { /* strcasecmp allows changing foo to Foo, etc. */ notify(player, T("You can't give a player that name.")); return; *** 1_7_7.561/src/predicat.c Mon, 11 Aug 2003 14:17:00 -0500 dunemush (pennmush/b/44_predicat.c 1.1.1.34.1.1.1.3.1.4.2.26 660) --- 1_7_7.623(w)/src/predicat.c Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/b/44_predicat.c 1.1.1.34.1.1.1.3.1.4.2.27 660) *************** *** 697,703 **** } /** Is a name a valid player name? ! * Player names must be valid object names, but also not forbidden, * subject to a different length limit, and subject to more stringent * restrictions on valid characters. Finally, it can't be the same as * an existing player name or alias. --- 697,704 ---- } /** Is a name a valid player name? ! * Player names must be valid object names, but also not forbidden (unless ! * the player is a wizard). They are * subject to a different length limit, and subject to more stringent * restrictions on valid characters. Finally, it can't be the same as * an existing player name or alias. *************** *** 706,717 **** * \retval 0 name is not valid for players. */ int ! ok_player_name(const char *name) { const unsigned char *scan, *good; ! if (!ok_name(name) || forbidden_name(name) || ! strlen(name) >= (size_t) PLAYER_NAME_LIMIT) return 0; good = (unsigned char *) (PLAYER_NAME_SPACES ? " `$_-.,'" : "`$_-.,'"); --- 707,719 ---- * \retval 0 name is not valid for players. */ int ! ok_player_name(const char *name, dbref player) { const unsigned char *scan, *good; ! if (!ok_name(name) ! || (forbidden_name(name) && !(GoodObject(player) && Wizard(player))) ! || strlen(name) >= (size_t) PLAYER_NAME_LIMIT) return 0; good = (unsigned char *) (PLAYER_NAME_SPACES ? " `$_-.,'" : "`$_-.,'"); *** 1_7_7.561/src/player.c Tue, 19 Aug 2003 12:07:25 -0500 dunemush (pennmush/b/47_player.c 1.15.1.1.1.1.1.4.1.6.1.1.1.4 660) --- 1_7_7.623(w)/src/player.c Wed, 10 Sep 2003 14:47:28 -0500 dunemush (pennmush/b/47_player.c 1.15.1.1.1.1.1.4.1.6.1.1.1.5 660) *************** *** 203,209 **** create_player(const char *name, const char *password, const char *host, const char *ip) { ! if (!ok_player_name(name)) { do_log(LT_CONN, 0, 0, T("Failed creation (bad name) from %s"), host); return NOTHING; } --- 203,209 ---- create_player(const char *name, const char *password, const char *host, const char *ip) { ! if (!ok_player_name(name, NOTHING)) { do_log(LT_CONN, 0, 0, T("Failed creation (bad name) from %s"), host); return NOTHING; } *************** *** 254,260 **** dbref player; FILE *fp; ! if (!ok_player_name(name)) { do_log(LT_CONN, 0, 0, T("Failed registration (bad name) from %s"), host); return NOTHING; } --- 254,260 ---- dbref player; FILE *fp; ! if (!ok_player_name(name, NOTHING)) { do_log(LT_CONN, 0, 0, T("Failed registration (bad name) from %s"), host); return NOTHING; } *** 1_7_7.561/src/parse.c Mon, 11 Aug 2003 16:10:20 -0500 dunemush (pennmush/b/48_parse.c 1.23.1.10.1.2.1.1.1.1.1.2.1.2.1.19 660) --- 1_7_7.623(w)/src/parse.c Wed, 10 Sep 2003 14:47:27 -0500 dunemush (pennmush/b/48_parse.c 1.23.1.10.1.2.1.1.1.1.1.2.1.2.1.22 660) *************** *** 465,471 **** if (eflags != PE_NOTHING) { ! debugging = Debug(executor) && Connected(Owner(executor)); if (debugging) { int j; char *debugp; --- 465,472 ---- if (eflags != PE_NOTHING) { ! debugging = Debug(executor) && (Connected(Owner(executor)) ! || atr_get(executor, "DEBUGFORWARDLIST")); if (debugging) { int j; char *debugp; *************** *** 835,845 **** --- 836,852 ---- (*str)++; if (!(eflags & PE_EVALUATE) || !(eflags & PE_FUNCTION_CHECK)) { safe_chr('(', buff, bp); + if (**str == ' ') { + safe_chr(**str, buff, bp); + (*str)++; + } if (process_expression(buff, bp, str, executor, caller, enactor, eflags & ~PE_STRIP_BRACES, PT_PAREN, pe_info)) retval = 1; if (**str == ')') { + if (eflags & PE_COMPRESS_SPACES && (*str)[-1] == ' ') + safe_chr(' ', buff, bp); safe_chr(')', buff, bp); (*str)++; } *************** *** 1148,1154 **** dbuf[0] = '\0'; safe_format(dbuf, &dbp, "%s :", pe_info->debug_strings->string); *dbp = '\0'; ! raw_notify(Owner(executor), dbuf); pe_info->debug_strings = pe_info->debug_strings->next; mush_free((Malloc_t) pe_info->debug_strings->prev, "process_expression.debug_node"); --- 1155,1164 ---- dbuf[0] = '\0'; safe_format(dbuf, &dbp, "%s :", pe_info->debug_strings->string); *dbp = '\0'; ! if (Connected(Owner(executor))) ! raw_notify(Owner(executor), dbuf); ! notify_list(executor, executor, "DEBUGFORWARDLIST", dbuf, ! NA_NOLISTEN | NA_NOPREFIX); pe_info->debug_strings = pe_info->debug_strings->next; mush_free((Malloc_t) pe_info->debug_strings->prev, "process_expression.debug_node"); *************** *** 1161,1167 **** dbuf[0] = '\0'; safe_format(dbuf, &dbp, "%s => %s", debugstr, startpos); *dbp = '\0'; ! raw_notify(Owner(executor), dbuf); } else { Debug_Info *node; node = pe_info->debug_strings; --- 1171,1180 ---- dbuf[0] = '\0'; safe_format(dbuf, &dbp, "%s => %s", debugstr, startpos); *dbp = '\0'; ! if (Connected(Owner(executor))) ! raw_notify(Owner(executor), dbuf); ! notify_list(executor, executor, "DEBUGFORWARDLIST", dbuf, ! NA_NOLISTEN | NA_NOPREFIX); } else { Debug_Info *node; node = pe_info->debug_strings; *** 1_7_7.561/src/look.c Mon, 11 Aug 2003 13:09:23 -0500 dunemush (pennmush/c/4_look.c 1.21.1.2.1.9.1.1.1.1.1.11 660) --- 1_7_7.623(w)/src/look.c Wed, 10 Sep 2003 14:47:27 -0500 dunemush (pennmush/c/4_look.c 1.21.1.2.1.9.1.1.1.1.1.12 660) *************** *** 437,443 **** /* don't give the unparse if looking through Transparent exit */ if (style == LOOK_NORMAL || style == LOOK_AUTO) { PUSE; ! tag("XCH_PAGE CLEAR=\"LINKS IMAGES PLUGINS\""); if (SUPPORT_PUEBLO && style == LOOK_AUTO) { a = atr_get(loc, "VRML_URL"); if (a) { --- 437,443 ---- /* don't give the unparse if looking through Transparent exit */ if (style == LOOK_NORMAL || style == LOOK_AUTO) { PUSE; ! tag("XCH_PAGE CLEAR=\"LINKS PLUGINS\""); if (SUPPORT_PUEBLO && style == LOOK_AUTO) { a = atr_get(loc, "VRML_URL"); if (a) { *** 1_7_7.561/src/lock.c Mon, 11 Aug 2003 13:48:34 -0500 dunemush (pennmush/c/6_lock.c 1.17.1.13.1.1.1.1.1.6 660) --- 1_7_7.623(w)/src/lock.c Wed, 10 Sep 2003 14:47:27 -0500 dunemush (pennmush/c/6_lock.c 1.17.1.13.1.1.1.1.1.7 660) *************** *** 79,84 **** --- 79,85 ---- const lock_type Control_Lock = "Control"; /**< Name of control lock */ const lock_type Dropto_Lock = "Dropto"; /**< Name of dropto lock */ const lock_type Destroy_Lock = "Destroy"; /**< Name of destroy lock */ + const lock_type Interact_Lock = "Interact"; /* Define new lock types here. */ /** Table of lock names and permissions */ *************** *** 105,110 **** --- 106,112 ---- {"Control", TRUE_BOOLEXP, GOD, LF_PRIVATE | LF_OWNER, NULL}, {"Dropto", TRUE_BOOLEXP, GOD, LF_PRIVATE, NULL}, {"Destroy", TRUE_BOOLEXP, GOD, LF_PRIVATE | LF_OWNER, NULL}, + {"Interact", TRUE_BOOLEXP, GOD, LF_PRIVATE, NULL}, /* Add new lock types just before this line. */ {NULL, TRUE_BOOLEXP, GOD, 0, NULL} }; *** 1_7_7.561/src/game.c Tue, 19 Aug 2003 12:07:25 -0500 dunemush (pennmush/c/10_game.c 1.50.1.8.1.1.1.1.2.1.1.1.2.1.1.4.1.1.1.1.1.1.1.1.1.1.2.1.1.2.1.1.1.1.1.1.1.2.1.1.1.2.1.1.1.1.1.1.1.1.1.5.1.3.1.2.1.2.1.1.1.1.1.1.1.1.1.12 660) --- 1_7_7.623(w)/src/game.c Wed, 10 Sep 2003 14:47:26 -0500 dunemush (pennmush/c/10_game.c 1.50.1.8.1.1.1.1.2.1.1.1.2.1.1.4.1.1.1.1.1.1.1.1.1.1.2.1.1.2.1.1.1.1.1.1.1.2.1.1.1.2.1.1.1.1.1.1.1.1.1.5.1.3.1.2.1.2.1.1.1.1.1.1.1.1.1.12.1.3 660) *************** *** 142,147 **** --- 142,149 ---- void do_timestring(char *buff, char **bp, const char *format, unsigned long secs); + void create_minimal_db(void); /* From db.c */ + dbref orator = NOTHING; /**< Last dbref to issue a speech command */ #ifdef COMP_STATS *************** *** 761,767 **** init_game_dbs(void) { FILE *f; ! const char *infile, *outfile; #ifdef USE_MAILER const char *mailfile; --- 763,769 ---- init_game_dbs(void) { FILE *f; ! int c; const char *infile, *outfile; #ifdef USE_MAILER const char *mailfile; *************** *** 780,793 **** #ifdef USE_MAILER mailfile = options.mail_db; #endif /* read small text files into cache */ fcache_init(); f = db_open(infile); ! if (!f) ! return -1; /* ok, read it in */ do_rawlog(LT_ERR, "ANALYZING: %s", infile); --- 782,810 ---- #ifdef USE_MAILER mailfile = options.mail_db; #endif + strcpy(dumpfile, outfile); /* read small text files into cache */ fcache_init(); f = db_open(infile); ! if (!f) { ! do_rawlog(LT_ERR, "Couldn't open %s! Creating minimal world.", infile); ! init_compress(NULL); ! create_minimal_db(); ! return 0; ! } ! ! c = getc(f); ! if (c == EOF) { ! do_rawlog(LT_ERR, "Couldn't read %s! Creating minimal world.", infile); ! init_compress(NULL); ! create_minimal_db(); ! return 0; ! } ! ! ungetc(c, f); /* ok, read it in */ do_rawlog(LT_ERR, "ANALYZING: %s", infile); *************** *** 892,900 **** if (panicdb) db_close(f); - /* set up dumper */ - strcpy(dumpfile, outfile); - return 0; } --- 909,914 ---- *************** *** 1522,1527 **** --- 1536,1542 ---- char *ptr; dbref thing; int num; + char save_ccom[BUFFER_LEN]; ptr = atrname; if (!GoodObject(Location(player))) { *************** *** 1532,1537 **** --- 1547,1554 ---- notify(player, T("What command do you want to scan for?")); return; } + strcpy(save_ccom, ccom); + memmove(ccom, (char *) ccom + 5, BUFFER_LEN - 5); if (flag & CHECK_NEIGHBORS) { notify(player, T("Matches on contents of this room:")); DOLIST(thing, Contents(Location(player))) { *************** *** 1638,1643 **** --- 1655,1661 ---- } } } + strcpy(ccom, save_ccom); } #define DOL_MAP 1 /**< The map command */ *** 1_7_7.561/src/funstr.c Mon, 11 Aug 2003 19:49:47 -0500 dunemush (pennmush/c/13_funstr.c 1.28.1.1.1.2.1.4.1.6.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.3.1.5.1.3.1.2.1.1.1.1.1.1.1.1.1.10 660) --- 1_7_7.623(w)/src/funstr.c Wed, 10 Sep 2003 14:47:26 -0500 dunemush (pennmush/c/13_funstr.c 1.28.1.1.1.2.1.4.1.6.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.3.1.5.1.3.1.2.1.1.1.1.1.1.1.1.1.11 660) *************** *** 636,643 **** /* walk strings, copy from the appropriate string */ for (str = args[0], rep = args[1]; *str && *rep; str++, rep++) { ! safe_chr((*str == c) ? *rep : *str, buff, bp); } } /* ARGSUSED */ --- 636,644 ---- /* walk strings, copy from the appropriate string */ for (str = args[0], rep = args[1]; *str && *rep; str++, rep++) { ! *str = (*str == c) ? *rep : *str; } + safe_str(args[0], buff, bp); } /* ARGSUSED */ *** 1_7_7.561/src/funmisc.c Mon, 16 Jun 2003 23:53:35 -0500 dunemush (pennmush/c/14_funmisc.c 1.30.1.1.1.19 660) --- 1_7_7.623(w)/src/funmisc.c Wed, 10 Sep 2003 14:47:26 -0500 dunemush (pennmush/c/14_funmisc.c 1.30.1.1.1.22 660) *************** *** 34,39 **** --- 34,40 ---- extern time_t start_time, first_start_time; extern int reboot_count; extern FUN flist[]; + extern char ccom[BUFFER_LEN]; static char *soundex(char *str); extern char cf_motd_msg[BUFFER_LEN], cf_wizmotd_msg[BUFFER_LEN], cf_downmotd_msg[BUFFER_LEN], cf_fullmotd_msg[BUFFER_LEN]; *************** *** 43,49 **** FUNCTION(fun_valid) { /* Checks to see if a given is valid as a parameter of a ! * given type (such as an object name. */ if (!args[0] || !*args[0]) --- 44,50 ---- FUNCTION(fun_valid) { /* Checks to see if a given is valid as a parameter of a ! * given type (such as an object name.) */ if (!args[0] || !*args[0]) *************** *** 53,59 **** else if (!strcasecmp(args[0], "attrname")) safe_boolean(good_atr_name(upcasestr(args[1])), buff, bp); else if (!strcasecmp(args[0], "playername")) ! safe_boolean(ok_player_name(args[1]), buff, bp); else safe_str("#-1", buff, bp); } --- 54,60 ---- else if (!strcasecmp(args[0], "attrname")) safe_boolean(good_atr_name(upcasestr(args[1])), buff, bp); else if (!strcasecmp(args[0], "playername")) ! safe_boolean(ok_player_name(args[1], executor), buff, bp); else safe_str("#-1", buff, bp); } *************** *** 496,501 **** --- 497,503 ---- FUNCTION(fun_scan) { dbref thing; + char save_ccom[BUFFER_LEN]; thing = match_thing(executor, args[0]); if (!GoodObject(thing)) { *************** *** 507,511 **** --- 509,517 ---- safe_str("#-1", buff, bp); return; } + strcpy(save_ccom, ccom); + strncpy(ccom, args[1], BUFFER_LEN); + ccom[BUFFER_LEN - 1] = '\0'; safe_str(scan_list(thing, args[1]), buff, bp); + strcpy(ccom, save_ccom); } *** 1_7_7.561/src/fundb.c Mon, 18 Aug 2003 20:59:29 -0500 dunemush (pennmush/c/17_fundb.c 1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.7.1.3.1.3.1.3.1.2.1.2.1.3.2.1.2.1.2.1.1.1.1.4.1.1.1.1.1.1.1.1.1.1.1.3.1.1.2.2.2.1.1.1.1.1.1.17 660) --- 1_7_7.623(w)/src/fundb.c Wed, 10 Sep 2003 14:47:26 -0500 dunemush (pennmush/c/17_fundb.c 1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.7.1.3.1.3.1.3.1.2.1.2.1.3.2.1.2.1.2.1.1.1.1.4.1.1.1.1.1.1.1.1.1.1.1.3.1.1.2.2.2.1.1.1.1.1.1.19 660) *************** *** 1016,1021 **** --- 1016,1025 ---- case 'T': safe_boolean(IsThing(it), buff, bp); break; + case 'g': + case 'G': + safe_boolean(IsGarbage(it), buff, bp); + break; default: safe_str(T("#-1 NO SUCH TYPE"), buff, bp); break; *************** *** 1821,1827 **** } } if (!Search_All(executor)) { ! if (who != ANY_OWNER && who != executor) { safe_str(T(e_perm), buff, bp); return; } --- 1825,1831 ---- } } if (!Search_All(executor)) { ! if (who != ANY_OWNER && !controls(executor, who)) { safe_str(T(e_perm), buff, bp); return; } *** 1_7_7.561/src/flags.c Mon, 18 Aug 2003 20:59:29 -0500 dunemush (pennmush/c/20_flags.c 1.1.1.1.1.1.1.1.1.1.1.1.1.6.1.2.1.1.1.1.1.2.2.2.2.1.2.1.1.3.1.2.1.1.1.1.1.1.1.1.1.3.1.9.1.2.2.1.1.2.1.53 660) --- 1_7_7.623(w)/src/flags.c Wed, 10 Sep 2003 14:47:26 -0500 dunemush (pennmush/c/20_flags.c 1.1.1.1.1.1.1.1.1.1.1.1.1.6.1.2.1.1.1.1.1.2.2.2.2.1.2.1.1.3.1.2.1.1.1.1.1.1.1.1.1.3.1.9.1.2.2.1.1.2.1.56 660) *************** *** 104,110 **** {"ANSI", 'A', TYPE_PLAYER, PLAYER_ANSI, F_ANY, F_ANY}, {"COLOR", 'C', TYPE_PLAYER, PLAYER_COLOR, F_ANY, F_ANY}, {"MONITOR", 'M', TYPE_PLAYER | TYPE_ROOM | TYPE_THING, 0, F_ANY, F_ANY}, ! {"NOSPOOF", 'N', TYPE_PLAYER, PLAYER_NOSPOOF, F_ANY | F_ODARK, F_ANY | F_ODARK}, {"SHARED", 'Z', TYPE_PLAYER, PLAYER_ZONE, F_ANY, F_ANY}, {"CONNECTED", 'c', TYPE_PLAYER, PLAYER_CONNECT, F_INTERNAL | F_MDARK, --- 104,110 ---- {"ANSI", 'A', TYPE_PLAYER, PLAYER_ANSI, F_ANY, F_ANY}, {"COLOR", 'C', TYPE_PLAYER, PLAYER_COLOR, F_ANY, F_ANY}, {"MONITOR", 'M', TYPE_PLAYER | TYPE_ROOM | TYPE_THING, 0, F_ANY, F_ANY}, ! {"NOSPOOF", '"', TYPE_PLAYER, PLAYER_NOSPOOF, F_ANY | F_ODARK, F_ANY | F_ODARK}, {"SHARED", 'Z', TYPE_PLAYER, PLAYER_ZONE, F_ANY, F_ANY}, {"CONNECTED", 'c', TYPE_PLAYER, PLAYER_CONNECT, F_INTERNAL | F_MDARK, *************** *** 125,131 **** #endif {"SUSPECT", 's', TYPE_PLAYER, PLAYER_SUSPECT, F_WIZARD | F_MDARK, F_WIZARD | F_MDARK}, ! {"PARANOID", 'p', TYPE_PLAYER, PLAYER_PARANOID, F_ANY | F_ODARK, F_ANY | F_ODARK}, {"NOACCENTS", '~', TYPE_PLAYER, PLAYER_NOACCENTS, F_ANY, F_ANY}, {"DESTROY_OK", 'd', TYPE_THING, THING_DEST_OK, F_ANY, F_ANY}, --- 125,131 ---- #endif {"SUSPECT", 's', TYPE_PLAYER, PLAYER_SUSPECT, F_WIZARD | F_MDARK, F_WIZARD | F_MDARK}, ! {"PARANOID", '\0', TYPE_PLAYER, PLAYER_PARANOID, F_ANY | F_ODARK, F_ANY | F_ODARK}, {"NOACCENTS", '~', TYPE_PLAYER, PLAYER_NOACCENTS, F_ANY, F_ANY}, {"DESTROY_OK", 'd', TYPE_THING, THING_DEST_OK, F_ANY, F_ANY}, *************** *** 340,349 **** static FLAG * new_flag(void) { ! /* We don't use mush_malloc, because these sometimes get freed ! * by ptab_free, which doesn't know how to handle the memcheck ! */ ! FLAG *f = (FLAG *) malloc(sizeof(FLAG)); if (!f) panic("Unable to allocate memory for a new flag!\n"); return f; --- 340,346 ---- static FLAG * new_flag(void) { ! FLAG *f = (FLAG *) mush_malloc(sizeof(FLAG), "flag"); if (!f) panic("Unable to allocate memory for a new flag!\n"); return f; *************** *** 365,371 **** clone_flag(FLAG *f) { FLAG *clone = new_flag(); ! clone->name = strdup(f->name); clone->letter = f->letter; clone->type = f->type; clone->bitpos = f->bitpos; --- 362,368 ---- clone_flag(FLAG *f) { FLAG *clone = new_flag(); ! clone->name = mush_strdup(f->name, "flag name"); clone->letter = f->letter; clone->type = f->type; clone->bitpos = f->bitpos; *************** *** 471,479 **** { FLAG *f; char *c; ! c = strdup(getstring_noalloc(in)); if (!strcmp(c, "FLAG ALIASES")) { ! free((Malloc_t) c); return NULL; /* We're done */ } f = new_flag(); --- 468,476 ---- { FLAG *f; char *c; ! c = mush_strdup(getstring_noalloc(in), "flag name"); if (!strcmp(c, "FLAG ALIASES")) { ! mush_free(c, "flag name"); return NULL; /* We're done */ } f = new_flag(); *************** *** 493,501 **** FLAG *f; char *c; /* Real name first */ ! c = strdup(getstring_noalloc(in)); if (!strcmp(c, "END OF FLAGS")) { ! free((Malloc_t) c); return NULL; /* We're done */ } f = match_flag(c); --- 490,498 ---- FLAG *f; char *c; /* Real name first */ ! c = mush_strdup(getstring_noalloc(in), "flag alias"); if (!strcmp(c, "END OF FLAGS")) { ! mush_free(c, "flag alias"); return NULL; /* We're done */ } f = match_flag(c); *************** *** 505,516 **** T ("FLAG READ: flag alias %s matches no known flag. Skipping aliases."), c); ! free((Malloc_t) c); do { c = (char *) getstring_noalloc(in); } while (strcmp(c, "END OF FLAGS")); return NULL; ! } /* Get the alias name */ strcpy(alias, getstring_noalloc(in)); return f; --- 502,515 ---- T ("FLAG READ: flag alias %s matches no known flag. Skipping aliases."), c); ! mush_free(c, "flag alias"); do { c = (char *) getstring_noalloc(in); } while (strcmp(c, "END OF FLAGS")); return NULL; ! } else ! mush_free(c, "flag alias"); ! /* Get the alias name */ strcpy(alias, getstring_noalloc(in)); return f; *************** *** 671,676 **** --- 670,683 ---- add_flag("ORPHAN", 'i', NOTYPE, F_ANY, F_ANY); if ((f = match_flag("TERSE"))) f->type |= TYPE_THING; + if ((f = match_flag("NOSPOOF"))) { + f->type = NOTYPE; + f->letter = '"'; + } + if ((f = match_flag("PARANOID"))) { + f->type = NOTYPE; + f->letter = '\0'; + } local_flags(); } *************** *** 1003,1009 **** } if (!str) return bitmask; /* We're done, then */ ! copy = strdup(str); s = trim_space_sep(copy, ' '); while (s) { sp = split_token(&s, ' '); --- 1010,1016 ---- } if (!str) return bitmask; /* We're done, then */ ! copy = mush_strdup(str, "flagstring"); s = trim_space_sep(copy, ' '); while (s) { sp = split_token(&s, ' '); *************** *** 1012,1018 **** continue; set_flag_bitmask(bitmask, f->bitpos); } ! free(copy); return bitmask; } --- 1019,1025 ---- continue; set_flag_bitmask(bitmask, f->bitpos); } ! mush_free(copy, "flagstring"); return bitmask; } *************** *** 1483,1489 **** /* Otherwise, we don't need to do anything. */ } } ! return (ret); } /** Check if an object has one or all of a list of flag names. --- 1490,1496 ---- /* Otherwise, we don't need to do anything. */ } } ! return ret; } /** Check if an object has one or all of a list of flag names. *************** *** 1513,1519 **** do_rawlog(LT_ERR, T("FLAG: Unable to locate flagspace %s"), ns); return 0; } ! copy = strdup(fstr); sp = trim_space_sep(copy, ' '); while (sp) { s = split_token(&sp, ' '); --- 1520,1526 ---- do_rawlog(LT_ERR, T("FLAG: Unable to locate flagspace %s"), ns); return 0; } ! copy = mush_strdup(fstr, "flaglistlong"); sp = trim_space_sep(copy, ' '); while (sp) { s = split_token(&sp, ' '); *************** *** 1527,1545 **** negate = 0; /* It's important to clear this at appropriate times; * else !D c means (!D && !c), instead of (!D && c). */ } ! if (!*s) /* We got a '!' that wasn't followed by a string. * Fail the check. */ ! return (type == 1) ? 0 : ret; /* Find the flag. */ if (!(fp = flag_hash_lookup(n, s, Typeof(it)))) { /* Either we got a '!' that wasn't followed by a letter, or * we couldn't find that flag. For AND, since we've failed * a check, we can return false. Otherwise we just go on. */ ! if (type == 1) ! return 0; ! else continue; } else { /* does the object have this flag? There's a special case --- 1534,1556 ---- negate = 0; /* It's important to clear this at appropriate times; * else !D c means (!D && !c), instead of (!D && c). */ } ! if (!*s) { /* We got a '!' that wasn't followed by a string. * Fail the check. */ ! if (type == 1) ! ret = 0; ! break; ! } /* Find the flag. */ if (!(fp = flag_hash_lookup(n, s, Typeof(it)))) { /* Either we got a '!' that wasn't followed by a letter, or * we couldn't find that flag. For AND, since we've failed * a check, we can return false. Otherwise we just go on. */ ! if (type == 1) { ! ret = 0; ! break; ! } else continue; } else { /* does the object have this flag? There's a special case *************** *** 1562,1568 **** * it, or we don't have a flag and we want it. Since it's * AND, we return false. */ ! return 0; } else if ((type == 0) && ((!negate && temp) || (negate && !temp))) { /* We've found something we want, in an OR. We OR a * true with the current value. --- 1573,1580 ---- * it, or we don't have a flag and we want it. Since it's * AND, we return false. */ ! ret = 0; ! break; } else if ((type == 0) && ((!negate && temp) || (negate && !temp))) { /* We've found something we want, in an OR. We OR a * true with the current value. *************** *** 1572,1578 **** /* Otherwise, we don't need to do anything. */ } } ! return (ret); } --- 1584,1591 ---- /* Otherwise, we don't need to do anything. */ } } ! mush_free(copy, "flaglistlong"); ! return ret; } *************** *** 1620,1626 **** return; n = hashfind("FLAG", &htab_flagspaces); f = new_flag(); ! f->name = strdup(strupper(name)); f->letter = letter; f->type = type; f->perms = perms; --- 1633,1639 ---- return; n = hashfind("FLAG", &htab_flagspaces); f = new_flag(); ! f->name = mush_strdup(strupper(name), "flag name"); f->letter = letter; f->type = type; f->perms = perms; *************** *** 1987,1994 **** /* Remove the flag from the ptab */ ptab_delete(n->tab, f->name); notify_format(player, T("Flag %s deleted."), f->name); ! /* Free the flag. Don't use mush_free, see new_flag() */ ! free((Malloc_t) f); } /** Enable a disabled flag. --- 2000,2008 ---- /* Remove the flag from the ptab */ ptab_delete(n->tab, f->name); notify_format(player, T("Flag %s deleted."), f->name); ! /* Free the flag. */ ! mush_free((char *) f->name, "flag name"); ! mush_free(f, "flag"); } /** Enable a disabled flag. *** 1_7_7.561/src/filecopy.c Sun, 01 Dec 2002 21:14:41 -0600 dunemush (pennmush/c/21_filecopy.c 1.77 660) --- 1_7_7.623(w)/src/filecopy.c Wed, 10 Sep 2003 14:47:26 -0500 dunemush (pennmush/c/21_filecopy.c 1.80 660) *************** *** 1,321 **** ! /* Win32 services routines */ ! ! /* Author: Nick Gammon */ ! ! #ifdef WIN32 ! ! #include "copyrite.h" ! #include "config.h" ! ! #include /* for find first */ ! ! #include ! #include ! #include ! ! #include "conf.h" ! #include "mushdb.h" ! #include "match.h" ! #include "externs.h" ! #include "mymalloc.h" ! #include "log.h" ! #include "confmagic.h" ! ! /* This is bad, but only for WIN32, which is bad anyway... */ ! #define EMBEDDED_MKINDX ! ! static char buff[1024]; ! ! BOOL ! ConcatenateFiles(const char *path, const char *outputfile) { ! HANDLE filscan; ! WIN32_FIND_DATA fildata; ! BOOL filflag; ! DWORD status; ! FILE *fo = NULL; ! FILE *f = NULL; ! size_t bytes_in, bytes_out; ! long total_bytes = 0; ! int total_files = 0; ! char directory[MAX_PATH]; ! char fullname[MAX_PATH]; ! ! char *p; ! ! /* If outputfile is an empty string, forget it. */ ! if (!outputfile || !*outputfile) ! return FALSE; ! ! /* extract the directory from the path name */ ! ! strcpy(directory, path); ! p = strrchr(directory, '\\'); ! if (p) ! p[1] = 0; else { ! p = strrchr(directory, '/'); ! if (p) ! p[1] = 0; ! } ! ! /* Open output file */ ! ! fo = fopen(outputfile, "wb"); ! ! if (!fo) { ! do_rawlog(LT_ERR, T("Unable to open file: %s"), outputfile); ! return FALSE; ! } ! do_rawlog(LT_ERR, T("Creating file: %s"), outputfile); ! ! /* Find first file matching the wildcard */ ! ! filscan = FindFirstFile(path, &fildata); ! if (filscan == INVALID_HANDLE_VALUE) { ! status = GetLastError(); ! ! fclose(fo); ! ! do_rawlog(LT_ERR, "**** No files matching: \"%s\" found.", path); ! ! if (status == ERROR_NO_MORE_FILES) ! return TRUE; else ! return FALSE; ! } ! /* ! Now enter the concatenation loop. ! */ ! do { ! if (!(fildata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { ! ! do_rawlog(LT_ERR, "%s: %s, %ld %s", ! T(" Copying file"), ! fildata.cFileName, ! fildata.nFileSizeLow, ! fildata.nFileSizeLow == 1 ? T("byte") : T("bytes")); ! ! strcpy(fullname, directory); ! strcat(fullname, fildata.cFileName); ! ! /* Open the input file */ ! ! f = fopen(fullname, "rb"); ! ! if (!f) ! do_rawlog(LT_ERR, T(" ** Unable to open file: %s"), fullname); else { ! ! total_files++; ! ! /* do the copy loop */ ! ! while (!feof(f)) { ! bytes_in = fread(buff, 1, sizeof(buff), f); ! if (bytes_in <= 0) ! break; ! ! bytes_out = fwrite(buff, 1, bytes_in, fo); ! total_bytes += bytes_out; ! if (bytes_in != bytes_out) { ! do_rawlog(LT_ERR, T("Unable to write to file: %s"), outputfile); ! fclose(f); ! break; ! } ! } /* end of copy loop */ ! ! ! fclose(f); ! } /* end of being able to open file */ ! ! } ! /* end of not being a directory */ ! /* get next file matching the wildcard */ ! filflag = FindNextFile(filscan, &fildata); ! } while (filflag); ! ! status = GetLastError(); ! ! FindClose(filscan); ! ! fclose(fo); ! ! do_rawlog(LT_ERR, T("Copied %i %s, %ld %s"), ! total_files, ! total_files == 1 ? T("file") : T("files"), ! total_bytes, total_bytes == 1 ? T("byte") : T("bytes")); ! ! if (status == ERROR_NO_MORE_FILES) ! return TRUE; else ! return FALSE; ! ! } ! ! int ! CheckDatabase(const char *path, FILETIME * modified, long *filesize) { ! HANDLE filscan; ! WIN32_FIND_DATA fildata; ! SYSTEMTIME st; ! static char *months[] = { ! ">!<", ! "Jan", "Feb", "Mar", "Apr", "May", "Jun", ! "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; ! FILE *f; ! size_t bytes; ! ! filscan = FindFirstFile(path, &fildata); ! if (filscan == INVALID_HANDLE_VALUE) { ! do_rawlog(LT_ERR, "File \"%s\" not found.", path); ! return FALSE; ! } ! *modified = fildata.ftLastWriteTime; ! *filesize = fildata.nFileSizeLow; ! ! FindClose(filscan); ! ! FileTimeToSystemTime(&fildata.ftLastWriteTime, &st); ! ! if (st.wMonth < 1 || st.wMonth > 12) ! st.wMonth = 0; ! ! do_rawlog(LT_ERR, ! T ! ("File \"%s\" found, size %ld %s, modified on %02d %s %04d %02d:%02d:%02d"), ! path, fildata.nFileSizeLow, ! fildata.nFileSizeLow == 1 ? T("byte") : T("bytes"), st.wDay, ! months[st.wMonth], st.wYear, st.wHour, st.wMinute, st.wSecond); ! ! if (fildata.nFileSizeHigh == 0 && fildata.nFileSizeLow < 80) { ! do_rawlog(LT_ERR, T("File is too small to be a MUSH database.")); ! return FALSE; ! } ! /* check file for validity */ ! ! f = fopen(path, "rb"); ! ! if (!f) { ! do_rawlog(LT_ERR, T("Unable to open file %s"), path); ! return FALSE; ! } ! if (fseek(f, -80, SEEK_END) != 0) { ! do_rawlog(LT_ERR, T("Unable to check file %s"), path); ! fclose(f); ! return FALSE; ! } ! bytes = fread(buff, 1, 80, f); ! ! fclose(f); ! ! if (bytes != 80) { ! do_rawlog(LT_ERR, T("Unable to read last part of file %s"), path); ! return FALSE; ! } ! if (strstr(buff, "***END OF DUMP***") == 0) { ! do_rawlog(LT_ERR, T("Database not terminated correctly, file %s"), path); ! return FALSE; ! } ! return TRUE; ! ! } /* end of CheckDatabase */ ! ! void ! Win32MUSH_setup(void) { ! int indb_OK, outdb_OK, panicdb_OK; ! ! FILETIME indb_time, outdb_time, panicdb_time; ! ! long indb_size, outdb_size, panicdb_size; ! ! char FileName[256]; ! ! if (GetModuleFileName(NULL, FileName, 256) != 0) { ! if (!strcasecmp(rindex(FileName, '\\') + 1, "pennmush.exe")) { ! if (CopyFile("pennmush.exe", "pennmush_run.exe", FALSE)) { ! do_rawlog(LT_ERR, "Successfully copied executable, starting copy."); ! execl("pennmush_run.exe", "pennmush_run.exe", "/run", NULL); ! } ! } ! } ! ! ConcatenateFiles("txt\\hlp\\*.hlp", "txt\\help.txt"); ! ConcatenateFiles("txt\\nws\\*.nws", "txt\\news.txt"); ! ConcatenateFiles("txt\\evt\\*.evt", "txt\\events.txt"); ! ConcatenateFiles("txt\\rul\\*.rul", "txt\\rules.txt"); ! ConcatenateFiles("txt\\idx\\*.idx", "txt\\index.txt"); ! ! indb_OK = CheckDatabase(options.input_db, &indb_time, &indb_size); ! outdb_OK = CheckDatabase(options.output_db, &outdb_time, &outdb_size); ! panicdb_OK = CheckDatabase(options.crash_db, &panicdb_time, &panicdb_size); ! ! if (indb_OK) { /* Look at outdb */ ! if (outdb_OK) { /* Look at panicdb */ ! if (panicdb_OK) { /* outdb or panicdb or indb */ ! if (CompareFileTime(&panicdb_time, &outdb_time) > 0) { /* panicdb or indb */ ! ! if (CompareFileTime(&panicdb_time, &indb_time) > 0) { /* panicdb */ ! ! ConcatenateFiles(options.crash_db, options.input_db); ! } else { /* indb */ ! } ! } else { /* outdb or indb */ ! if (CompareFileTime(&outdb_time, &indb_time) > 0) { /* outdb */ ! ! ConcatenateFiles(options.output_db, options.input_db); ! } else { /* indb */ ! } ! } ! } else { /* outdb or indb */ ! if (CompareFileTime(&outdb_time, &indb_time) > 0) { /* outdb */ ! ! ConcatenateFiles(options.output_db, options.input_db); ! } else { /* indb */ ! } ! } ! } else { /* outdb not OK */ ! if (panicdb_OK) { /* panicdb or indb */ ! if (CompareFileTime(&panicdb_time, &indb_time) > 0) { /* panicdb */ ! ! ConcatenateFiles(options.crash_db, options.input_db); ! } else { /* indb */ ! } ! } else { /* indb */ ! } ! } ! } else { /* indb not OK */ ! if (outdb_OK) { /* look at panicdb */ ! if (panicdb_OK) { /* out or panic */ ! if (CompareFileTime(&panicdb_time, &outdb_time) > 0) { /* panicdb */ ! ! ConcatenateFiles(options.crash_db, options.input_db); ! } else { /* outdb */ ! ! ConcatenateFiles(options.output_db, options.input_db); ! } ! } else { /* outdb */ ! ConcatenateFiles(options.output_db, options.input_db); ! } ! } else { /* outdb not OK */ ! if (panicdb_OK) { /* panicdb */ ! ConcatenateFiles(options.crash_db, options.input_db); ! } else { /* NOTHING */ ! exit(-1); ! } ! } ! } ! /* Final failsafe - input database SHOULD still be OK. */ ! do_rawlog(LT_ERR, T("Verifying selected database.")); ! if (!CheckDatabase(options.input_db, &indb_time, &indb_size)) { ! do_rawlog(LT_ERR, T("File corrupted during selection process.")); ! exit(-1); ! } else { ! do_rawlog(LT_ERR, T("Input database verified. Proceeding to analysis.")); ! } ! } ! #endif /* WIN32 */ --- 1,275 ---- ! /* Win32 services routines */ ! ! /* Author: Nick Gammon */ ! ! #ifdef WIN32 ! ! #include "copyrite.h" ! #include "config.h" ! ! #include /* for find first */ ! ! #include ! #include ! #include ! ! #include "conf.h" ! #include "mushdb.h" ! #include "match.h" ! #include "externs.h" ! #include "mymalloc.h" ! #include "log.h" ! #include "confmagic.h" ! ! /* This is bad, but only for WIN32, which is bad anyway... */ ! #define EMBEDDED_MKINDX ! static char buff[1024]; ! BOOL ConcatenateFiles(const char *path, const char *outputfile) { ! HANDLE filscan; ! WIN32_FIND_DATA fildata; ! BOOL filflag; ! DWORD status; ! FILE * fo = NULL; ! FILE * f = NULL; ! size_t bytes_in, bytes_out; ! long total_bytes = 0; ! int total_files = 0; ! char directory[MAX_PATH]; ! char fullname[MAX_PATH]; ! char *p; ! ! /* If outputfile is an empty string, forget it. */ ! if (!outputfile || !*outputfile) ! return FALSE; ! ! /* extract the directory from the path name */ ! strcpy(directory, path); ! p = strrchr(directory, '\\'); ! if (p) ! p[1] = 0; ! else { ! p = strrchr(directory, '/'); ! if (p) ! p[1] = 0; ! } ! ! /* Open output file */ ! fo = fopen(outputfile, "wb"); ! if (!fo) { ! do_rawlog(LT_ERR, T("Unable to open file: %s"), outputfile); ! return FALSE; ! } ! do_rawlog(LT_ERR, T("Creating file: %s"), outputfile); ! ! /* Find first file matching the wildcard */ ! filscan = FindFirstFile(path, &fildata); ! if (filscan == INVALID_HANDLE_VALUE) { ! status = GetLastError(); ! fclose(fo); ! do_rawlog(LT_ERR, "**** No files matching: \"%s\" found.", path); ! if (status == ERROR_NO_MORE_FILES) ! return TRUE; ! else ! return FALSE; ! } ! ! /* ! Now enter the concatenation loop. ! */ ! do { ! if (!(fildata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { ! do_rawlog(LT_ERR, "%s: %s, %ld %s", T(" Copying file"), ! fildata.cFileName, fildata.nFileSizeLow, ! fildata.nFileSizeLow == 1 ? T("byte") : T("bytes")); ! strcpy(fullname, directory); ! strcat(fullname, fildata.cFileName); ! ! /* Open the input file */ ! f = fopen(fullname, "rb"); ! if (!f) ! do_rawlog(LT_ERR, T(" ** Unable to open file: %s"), fullname); ! else { ! total_files++; ! ! /* do the copy loop */ ! while (!feof(f)) { ! bytes_in = fread(buff, 1, sizeof(buff), f); ! if (bytes_in <= 0) ! break; ! bytes_out = fwrite(buff, 1, bytes_in, fo); ! total_bytes += bytes_out; ! if (bytes_in != bytes_out) { ! do_rawlog(LT_ERR, T("Unable to write to file: %s"), outputfile); ! fclose(f); ! break; ! } ! } /* end of copy loop */ ! fclose(f); ! } /* end of being able to open file */ ! } ! ! /* end of not being a directory */ ! /* get next file matching the wildcard */ ! filflag = FindNextFile(filscan, &fildata); ! } while (filflag); ! status = GetLastError(); ! FindClose(filscan); ! fclose(fo); ! do_rawlog(LT_ERR, T("Copied %i %s, %ld %s"), total_files, ! total_files == 1 ? T("file") : T("files"), total_bytes, ! total_bytes == 1 ? T("byte") : T("bytes")); ! if (status == ERROR_NO_MORE_FILES) ! return TRUE; ! else ! return FALSE; ! } ! int ! CheckDatabase(const char *path, FILETIME * modified, long *filesize) { ! HANDLE filscan; ! WIN32_FIND_DATA fildata; ! SYSTEMTIME st; ! static char *months[] = ! { ">!<", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", ! "Oct", "Nov", "Dec" }; ! FILE * f; ! size_t bytes; ! filscan = FindFirstFile(path, &fildata); ! if (filscan == INVALID_HANDLE_VALUE) { ! do_rawlog(LT_ERR, "File \"%s\" not found.", path); ! return FALSE; ! } ! *modified = fildata.ftLastWriteTime; ! *filesize = fildata.nFileSizeLow; ! FindClose(filscan); ! FileTimeToSystemTime(&fildata.ftLastWriteTime, &st); ! if (st.wMonth < 1 || st.wMonth > 12) ! st.wMonth = 0; ! do_rawlog(LT_ERR, T ! ("File \"%s\" found, size %ld %s, modified on %02d %s %04d %02d:%02d:%02d"), ! path, fildata.nFileSizeLow, ! fildata.nFileSizeLow == 1 ? T("byte") : T("bytes"), st.wDay, ! months[st.wMonth], st.wYear, st.wHour, st.wMinute, st.wSecond); ! if (fildata.nFileSizeHigh == 0 && fildata.nFileSizeLow < 80) { ! do_rawlog(LT_ERR, T("File is too small to be a MUSH database.")); ! return FALSE; ! } ! ! /* check file for validity */ ! f = fopen(path, "rb"); ! if (!f) { ! do_rawlog(LT_ERR, T("Unable to open file %s"), path); ! return FALSE; ! } ! if (fseek(f, -80, SEEK_END) != 0) { ! do_rawlog(LT_ERR, T("Unable to check file %s"), path); ! fclose(f); ! return FALSE; ! } ! bytes = fread(buff, 1, 80, f); ! fclose(f); ! if (bytes != 80) { ! do_rawlog(LT_ERR, T("Unable to read last part of file %s"), path); ! return FALSE; ! } ! if (strstr(buff, "***END OF DUMP***") == 0) { ! do_rawlog(LT_ERR, T("Database not terminated correctly, file %s"), path); ! return FALSE; ! } ! return TRUE; ! } /* end of CheckDatabase */ ! void ! Win32MUSH_setup(void) { + int indb_OK, outdb_OK, panicdb_OK; + FILETIME indb_time, outdb_time, panicdb_time; + long indb_size, outdb_size, panicdb_size; + char FileName[256]; + + #ifndef _DEBUG + if (GetModuleFileName(NULL, FileName, 256) != 0) { + if (!strcasecmp(rindex(FileName, '\\') + 1, "pennmush.exe")) { + if (CopyFile("pennmush.exe", "pennmush_run.exe", FALSE)) { + do_rawlog(LT_ERR, "Successfully copied executable, starting copy."); + execl("pennmush_run.exe", "pennmush_run.exe", "/run", NULL); + } + } + } + + #endif /* */ + ConcatenateFiles("txt\\hlp\\*.hlp", "txt\\help.txt"); + ConcatenateFiles("txt\\nws\\*.nws", "txt\\news.txt"); + ConcatenateFiles("txt\\evt\\*.evt", "txt\\events.txt"); + ConcatenateFiles("txt\\rul\\*.rul", "txt\\rules.txt"); + ConcatenateFiles("txt\\idx\\*.idx", "txt\\index.txt"); + indb_OK = CheckDatabase(options.input_db, &indb_time, &indb_size); + outdb_OK = CheckDatabase(options.output_db, &outdb_time, &outdb_size); + panicdb_OK = CheckDatabase(options.crash_db, &panicdb_time, &panicdb_size); + if (indb_OK) { /* Look at outdb */ + if (outdb_OK) { /* Look at panicdb */ + if (panicdb_OK) { /* outdb or panicdb or indb */ + if (CompareFileTime(&panicdb_time, &outdb_time) > 0) { /* panicdb or indb */ + if (CompareFileTime(&panicdb_time, &indb_time) > 0) { /* panicdb */ + ConcatenateFiles(options.crash_db, options.input_db); + } else { /* indb */ + } + } else { /* outdb or indb */ + if (CompareFileTime(&outdb_time, &indb_time) > 0) { /* outdb */ + ConcatenateFiles(options.output_db, options.input_db); + } else { /* indb */ + } + } + } else { /* outdb or indb */ + if (CompareFileTime(&outdb_time, &indb_time) > 0) { /* outdb */ + ConcatenateFiles(options.output_db, options.input_db); + } else { /* indb */ + } + } + } else { /* outdb not OK */ + if (panicdb_OK) { /* panicdb or indb */ + if (CompareFileTime(&panicdb_time, &indb_time) > 0) { /* panicdb */ + ConcatenateFiles(options.crash_db, options.input_db); + } else { /* indb */ + } + } else { /* indb */ + } + } + } else { /* indb not OK */ + if (outdb_OK) { /* look at panicdb */ + if (panicdb_OK) { /* out or panic */ + if (CompareFileTime(&panicdb_time, &outdb_time) > 0) { /* panicdb */ + ConcatenateFiles(options.crash_db, options.input_db); + } else { /* outdb */ + ConcatenateFiles(options.output_db, options.input_db); + } + } else { /* outdb */ + ConcatenateFiles(options.output_db, options.input_db); + } + } else { /* outdb not OK */ + if (panicdb_OK) { /* panicdb */ + ConcatenateFiles(options.crash_db, options.input_db); + } else { /* NOTHING */ + exit(-1); + } + } + } + + /* Final failsafe - input database SHOULD still be OK. */ + do_rawlog(LT_ERR, T("Verifying selected database.")); + if (!CheckDatabase(options.input_db, &indb_time, &indb_size)) { + do_rawlog(LT_ERR, T("File corrupted during selection process.")); + exit(-1); + } else { + do_rawlog(LT_ERR, T("Input database verified. Proceeding to analysis.")); + } + } ! ! #endif /* WIN32 */ *** 1_7_7.561/src/extchat.c Mon, 11 Aug 2003 13:48:34 -0500 dunemush (pennmush/c/23_extchat.c 1.1.1.1.1.1.1.1.1.2.1.1.1.3.1.1.1.5.1.1.1.1.1.5.1.2.1.3.1.3.1.1.1.4.1.2.1.6.1.2.1.1.2.4.2.9.1.2.1.2.1.3.1.2.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.2.1.1.2.1.1.2.1.1.1.1.1.37 660) --- 1_7_7.623(w)/src/extchat.c Wed, 10 Sep 2003 14:47:26 -0500 dunemush (pennmush/c/23_extchat.c 1.1.1.1.1.1.1.1.1.2.1.1.1.3.1.1.1.5.1.1.1.1.1.5.1.2.1.3.1.3.1.1.1.4.1.2.1.6.1.2.1.1.2.4.2.9.1.2.1.2.1.3.1.2.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.2.1.1.2.1.1.2.1.1.1.1.1.37.1.2 660) *************** *** 974,980 **** T("CHAT: You join %s to channel <%s>."), Name(victim), ChanName(chan)); if (!Channel_Quiet(chan) && !DarkLegal(victim)) ! channel_broadcast(chan, victim, 1, T("<%s> %s has joined this channel."), ChanName(chan), Name(victim)); ChanNumUsers(chan)++; --- 974,980 ---- T("CHAT: You join %s to channel <%s>."), Name(victim), ChanName(chan)); if (!Channel_Quiet(chan) && !DarkLegal(victim)) ! channel_broadcast(chan, victim, CB_CHECKQUIET | CB_PRESENCE, T("<%s> %s has joined this channel."), ChanName(chan), Name(victim)); ChanNumUsers(chan)++; *************** *** 996,1002 **** } if (remove_user_by_dbref(victim, chan)) { if (!Channel_Quiet(chan) && !DarkLegal(victim)) ! channel_broadcast(chan, victim, 1, T("<%s> %s has left this channel."), ChanName(chan), Name(victim)); notify_format(victim, --- 996,1002 ---- } if (remove_user_by_dbref(victim, chan)) { if (!Channel_Quiet(chan) && !DarkLegal(victim)) ! channel_broadcast(chan, victim, CB_CHECKQUIET | CB_PRESENCE, T("<%s> %s has left this channel."), ChanName(chan), Name(victim)); notify_format(victim, *************** *** 1063,1069 **** if (insert_user_by_dbref(player, chan)) { notify_format(player, T("CHAT: You join channel <%s>."), ChanName(chan)); if (!Channel_Quiet(chan) && !DarkLegal(player)) ! channel_broadcast(chan, player, 1, T("<%s> %s has joined this channel."), ChanName(chan), Name(player)); ChanNumUsers(chan)++; --- 1063,1069 ---- if (insert_user_by_dbref(player, chan)) { notify_format(player, T("CHAT: You join channel <%s>."), ChanName(chan)); if (!Channel_Quiet(chan) && !DarkLegal(player)) ! channel_broadcast(chan, player, CB_CHECKQUIET | CB_PRESENCE, T("<%s> %s has joined this channel."), ChanName(chan), Name(player)); ChanNumUsers(chan)++; *************** *** 1098,1104 **** } if (remove_user_by_dbref(player, chan)) { if (!Channel_Quiet(chan) && !DarkLegal(player)) ! channel_broadcast(chan, player, 1, T("<%s> %s has left this channel."), ChanName(chan), Name(player)); notify_format(player, T("CHAT: You leave channel <%s>."), ChanName(chan)); --- 1098,1104 ---- } if (remove_user_by_dbref(player, chan)) { if (!Channel_Quiet(chan) && !DarkLegal(player)) ! channel_broadcast(chan, player, CB_CHECKQUIET | CB_PRESENCE, T("<%s> %s has left this channel."), ChanName(chan), Name(player)); notify_format(player, T("CHAT: You leave channel <%s>."), ChanName(chan)); *************** *** 1331,1339 **** return; } if (noisy) ! channel_broadcast(chan, player, 2, "<%s> %s", ChanName(chan), msg); else ! channel_broadcast(chan, player, 2, "%s", msg); if (!canhear) notify_format(player, T("Cemit to channel %s: %s"), ChanName(chan), msg); ChanNumMsgs(chan)++; --- 1331,1339 ---- return; } if (noisy) ! channel_broadcast(chan, player, CB_NOSPOOF, "<%s> %s", ChanName(chan), msg); else ! channel_broadcast(chan, player, CB_NOSPOOF, "%s", msg); if (!canhear) notify_format(player, T("Cemit to channel %s: %s"), ChanName(chan), msg); ChanNumMsgs(chan)++; *************** *** 1479,1485 **** remove_channel(chan); strcpy(ChanName(chan), perms); insert_channel(&chan); ! channel_broadcast(chan, player, 1, "<%s> %s has renamed channel %s to %s.", ChanName(chan), Name(player), old, ChanName(chan)); notify(player, T("Channel renamed.")); --- 1479,1485 ---- remove_channel(chan); strcpy(ChanName(chan), perms); insert_channel(&chan); ! channel_broadcast(chan, player, 0, "<%s> %s has renamed channel %s to %s.", ChanName(chan), Name(player), old, ChanName(chan)); notify(player, T("Channel renamed.")); *************** *** 2453,2459 **** if (u) { if (!Channel_Quiet(c) && (Channel_Admin(c) || Channel_Wizard(c) || (!Chanuser_Hide(u) && !Dark(player)))) ! channel_broadcast(c, player, 1, "<%s> %s", ChanName(c), msg); CUtype(u) &= ~CU_GAG; } } --- 2453,2460 ---- if (u) { if (!Channel_Quiet(c) && (Channel_Admin(c) || Channel_Wizard(c) || (!Chanuser_Hide(u) && !Dark(player)))) ! channel_broadcast(c, player, CB_CHECKQUIET | CB_PRESENCE, "<%s> %s", ! ChanName(c), msg); CUtype(u) &= ~CU_GAG; } } *************** *** 2725,2731 **** /** Broadcast a message to a channel. * \param channel pointer to channel to broadcast to. * \param player message speaker. ! * \param flags broadcast flag mask (0x1 = checkquiet, 0x2 = nospoof) * \param fmt message format string. */ void WIN32_CDECL --- 2726,2732 ---- /** Broadcast a message to a channel. * \param channel pointer to channel to broadcast to. * \param player message speaker. ! * \param flags broadcast flag mask (see CB_* constants in extchat.h) * \param fmt message format string. */ void WIN32_CDECL *************** *** 2755,2763 **** tbuf1[BUFFER_LEN - 1] = '\0'; nac.u = ChanUsers(channel); ! nac.checkquiet = (flags & CU_QUIET) ? 1 : 0; notify_anything(player, na_channel, &nac, ! (flags & CU_HIDE) ? ns_esnotify : NULL, 0, tbuf1); channel_push_buffer(channel, tbuf1); } --- 2756,2766 ---- tbuf1[BUFFER_LEN - 1] = '\0'; nac.u = ChanUsers(channel); ! nac.checkquiet = (flags & CB_CHECKQUIET) ? 1 : 0; notify_anything(player, na_channel, &nac, ! (flags & CB_NOSPOOF) ? ns_esnotify : NULL, ! (flags & CB_PRESENCE) ? NA_INTER_PRESENCE : NA_INTER_HEAR, ! tbuf1); channel_push_buffer(channel, tbuf1); } *** 1_7_7.561/src/db.c Mon, 18 Aug 2003 20:59:29 -0500 dunemush (pennmush/c/25_db.c 1.26.1.1.1.1.1.6.1.1.1.4 660) --- 1_7_7.623(w)/src/db.c Wed, 10 Sep 2003 14:47:26 -0500 dunemush (pennmush/c/25_db.c 1.26.1.1.1.1.1.6.1.1.1.6 660) *************** *** 35,40 **** --- 35,43 ---- #include "strtree.h" #include "parse.h" #include "htab.h" + #ifdef USE_MAILER + #include "extmail.h" + #endif #include "confmagic.h" #ifdef WIN32 *************** *** 92,97 **** --- 95,102 ---- void init_names(void); + void create_minimal_db(void); + extern struct db_stat_info current_state; /** Initialize the name strtree. *************** *** 1286,1288 **** --- 1291,1346 ---- set_objdata(thing, p, NULL); } } + + /** Create a basic 3-object (Start Room, God, Master Room) database. */ + void + create_minimal_db(void) + { + dbref start_room, god, master_room; + + int desc_flags = AF_VISUAL | AF_NOPROG | AF_PREFIXMATCH; + + start_room = new_object(); /* #0 */ + god = new_object(); /* #1 */ + master_room = new_object(); /* #2 */ + + set_name(start_room, "Room Zero"); + Type(start_room) = TYPE_ROOM; + Flags(start_room) = string_to_bits("FLAG", "LINK_OK"); + atr_new_add(start_room, "DESCRIBE", "You are in Room Zero.", GOD, desc_flags, + 1); + CreTime(start_room) = ModTime(start_room) = mudtime; + current_state.rooms++; + + set_name(god, "One"); + Type(god) = TYPE_PLAYER; + Flags(god) = string_to_bits("FLAG", "WIZARD"); + Location(god) = start_room; + Home(god) = start_room; + Owner(god) = god; + CreTime(god) = mudtime; + ModTime(god) = (time_t) 0; + add_lock(god, god, Basic_Lock, parse_boolexp(god, "=me", Basic_Lock), -1); + add_lock(god, god, Enter_Lock, parse_boolexp(god, "=me", Enter_Lock), -1); + add_lock(god, god, Use_Lock, parse_boolexp(god, "=me", Use_Lock), -1); + atr_new_add(god, "DESCRIBE", "You see Number One.", god, desc_flags, 1); + #ifdef USE_MAILER + atr_new_add(god, "MAILCURF", "0", god, AF_LOCKED | AF_NOPROG | AF_WIZARD, 1); + add_folder_name(god, 0, "inbox"); + #endif + PUSH(god, Contents(start_room)); + add_player(god, NULL); + s_Pennies(god, START_BONUS); + local_data_create(god); + current_state.players++; + + set_name(master_room, "Master Room"); + Type(master_room) = TYPE_ROOM; + Flags(master_room) = string_to_bits("FLAG", "FLOATING"); + Owner(master_room) = god; + CreTime(master_room) = ModTime(master_room) = mudtime; + atr_new_add(master_room, "DESCRIBE", + "This is the master room. Any exit in here is considered global. The same is true for objects with $-commands placed here.", + god, desc_flags, 1); + current_state.rooms++; + } *** 1_7_7.561/src/conf.c Sun, 17 Aug 2003 08:30:54 -0500 dunemush (pennmush/c/31_conf.c 1.41.2.3.1.3.1.2.1.15.1.1.1.1.1.1.1.6 660) --- 1_7_7.623(w)/src/conf.c Wed, 10 Sep 2003 14:47:25 -0500 dunemush (pennmush/c/31_conf.c 1.41.2.3.1.3.1.2.1.15.1.1.1.1.1.1.1.7 660) *************** *** 906,912 **** return 0; } } else if (restrictions) { ! return 1; } /* search conf table for the option; if found, add it, if not found, * complain about it. Forbid use of @config to set options without --- 906,912 ---- return 0; } } else if (restrictions) { ! return 0; } /* search conf table for the option; if found, add it, if not found, * complain about it. Forbid use of @config to set options without *** 1_7_7.561/src/comp_h.c Mon, 28 Apr 2003 00:35:06 -0500 dunemush (pennmush/c/34_comp_h.c 1.17 660) --- 1_7_7.623(w)/src/comp_h.c Wed, 10 Sep 2003 14:47:25 -0500 dunemush (pennmush/c/34_comp_h.c 1.19 660) *************** *** 355,366 **** #endif /* Part 2: count frequencies */ ! total = 0; ! while (!feof(f) && (!SAMPLE_SIZE || (total++ < SAMPLE_SIZE))) { ! c = fgetc(f); ! table[c].freq++; } - #ifdef STANDALONE for (indx = 0; indx < TABLE_SIZE; indx++) { printf(isprint(indx) ? "Frequency for '%c': %d\n" --- 355,367 ---- #endif /* Part 2: count frequencies */ ! if (f) { ! total = 0; ! while (!feof(f) && (!SAMPLE_SIZE || (total++ < SAMPLE_SIZE))) { ! c = fgetc(f); ! table[c].freq++; ! } } #ifdef STANDALONE for (indx = 0; indx < TABLE_SIZE; indx++) { printf(isprint(indx) ? "Frequency for '%c': %d\n" *************** *** 386,392 **** /* The DEL character is returned once for no apparent reason (I think * it is returned at EOF), so remove that one count... */ ! table[255].freq--; /* Newlines really aren't all that common in the attributes, so * chop the value substantially. --- 387,394 ---- /* The DEL character is returned once for no apparent reason (I think * it is returned at EOF), so remove that one count... */ ! if (table[255].freq) ! table[255].freq--; /* Newlines really aren't all that common in the attributes, so * chop the value substantially. *** 1_7_7.561/src/command.c Mon, 18 Aug 2003 20:59:29 -0500 dunemush (pennmush/c/36_command.c 1.56.1.1.1.1.1.1.1.2.1.1.1.1.1.5.1.2.1.1.1.1.1.2.1.3.1.10.1.1.3.11 660) --- 1_7_7.623(w)/src/command.c Wed, 10 Sep 2003 14:47:25 -0500 dunemush (pennmush/c/36_command.c 1.56.1.1.1.1.1.1.1.2.1.1.1.1.1.5.1.2.1.1.1.1.1.2.1.3.1.10.1.1.3.20 660) *************** *** 48,60 **** static int command_check(dbref player, COMMAND_INFO *cmd); static int switch_find(COMMAND_INFO *cmd, char *sw); static void strccat(char *buff, char **bp, const char *from); extern int global_fun_invocations; /**< Counter for function invocations */ extern int global_fun_recursions; /**< Counter for function recursion */ ! void run_hook(dbref player, dbref cause, struct hook_data *hook, ! char *saveregs[], int save); ! void do_hook(dbref player, char *command, char *obj, char *attrname, ! int hook_type); /** The list of standard commands. Additional commands can be added * at runtime with add_command(). --- 48,60 ---- static int command_check(dbref player, COMMAND_INFO *cmd); static int switch_find(COMMAND_INFO *cmd, char *sw); static void strccat(char *buff, char **bp, const char *from); + static int has_hook(struct hook_data *hook); extern int global_fun_invocations; /**< Counter for function invocations */ extern int global_fun_recursions; /**< Counter for function recursion */ ! int run_hook(dbref player, dbref cause, struct hook_data *hook, ! char *saveregs[], int save); ! extern char ccom[]; /** The list of standard commands. Additional commands can be added * at runtime with add_command(). *************** *** 150,156 **** CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_NOPARSE | CMD_T_NOGAGGED, 0, 0}, {"@HALT", "ALL", cmd_halt, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0}, {"@HIDE", "NO OFF YES ON", cmd_hide, CMD_T_ANY, 0, 0}, ! {"@HOOK", "AFTER BEFORE", cmd_hook, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS, "WIZARD", 0}, {"@KICK", NULL, cmd_kick, CMD_T_ANY, "WIZARD", 0}, --- 150,157 ---- CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_NOPARSE | CMD_T_NOGAGGED, 0, 0}, {"@HALT", "ALL", cmd_halt, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0}, {"@HIDE", "NO OFF YES ON", cmd_hide, CMD_T_ANY, 0, 0}, ! {"@HOOK", "AFTER BEFORE IGNORE OVERRIDE", cmd_hook, ! CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS, "WIZARD", 0}, {"@KICK", NULL, cmd_kick, CMD_T_ANY, "WIZARD", 0}, *************** *** 429,434 **** --- 430,439 ---- cmd->hooks.before.attrname = NULL; cmd->hooks.after.obj = NOTHING; cmd->hooks.after.attrname = NULL; + cmd->hooks.ignore.obj = NOTHING; + cmd->hooks.ignore.attrname = NULL; + cmd->hooks.override.obj = NOTHING; + cmd->hooks.override.attrname = NULL; return cmd; } *************** *** 813,823 **** char *ap, *swp; const char *attrib, *replacer; COMMAND_INFO *cmd; ! char *p, *t, *c; char b; int switchnum; switch_mask sw; int noeval; rhs_present = 0; --- 818,831 ---- char *ap, *swp; const char *attrib, *replacer; COMMAND_INFO *cmd; ! char *p, *t, *c, *c2; ! char command2[BUFFER_LEN]; char b; int switchnum; switch_mask sw; int noeval; + int noevtoken = 0; + char *retval; rhs_present = 0; *************** *** 836,841 **** --- 844,855 ---- /* All those one character commands.. Sigh */ global_fun_invocations = global_fun_recursions = 0; + if (*p == NOEVAL_TOKEN) { + noevtoken = 1; + p = string + 1; + string = p; + memmove(ccom, (char *) ccom + 1, BUFFER_LEN - 1); + } switch (*p) { case '#': if (!Gagged(player) && Mobile(player)) *************** *** 895,901 **** while (*p == ' ') p++; process_expression(command, &c, (const char **) &p, player, cause, cause, ! (PE_DEFAULT & ~PE_FUNCTION_CHECK) | PE_COMMAND_BRACES, PT_SPACE, NULL); *c = '\0'; strcpy(commandraw, command); --- 909,916 ---- while (*p == ' ') p++; process_expression(command, &c, (const char **) &p, player, cause, cause, ! noevtoken ? PE_NOTHING : ! ((PE_DEFAULT & ~PE_FUNCTION_CHECK) | PE_COMMAND_BRACES), PT_SPACE, NULL); *c = '\0'; strcpy(commandraw, command); *************** *** 925,968 **** cmd = command_find(replacer); p++; } /* Test if this either isn't a command, or is a disabled one * If so, return Fully Parsed string for further processing. */ if (!cmd || (cmd->type & CMD_T_DISABLED)) { - if (!cmd) { - c = commandraw + strlen(commandraw); - } else { - if (replacer) { - /* These commands don't allow switches, and need a space - * added after their canonical name - */ - c = commandraw; - safe_str(cmd->name, commandraw, &c); - safe_chr(' ', commandraw, &c); - } else if (*c == '/') { - /* Oh... DAMN */ - c = commandraw; - strcpy(switches, commandraw); - safe_str(cmd->name, commandraw, &c); - t = strchr(switches, '/'); - safe_str(t, commandraw, &c); - } else { - c = commandraw; - safe_str(cmd->name, commandraw, &c); - } - } if (*p) { if (*p == ' ') { ! safe_chr(' ', commandraw, &c); p++; } ! process_expression(commandraw, &c, (const char **) &p, player, cause, ! cause, ! (PE_DEFAULT & ~PE_FUNCTION_CHECK) | PE_COMMAND_BRACES, ! PT_DEFAULT, NULL); } ! *c = '\0'; mush_free((Malloc_t) command, "string"); mush_free((Malloc_t) swtch, "string"); mush_free((Malloc_t) ls, "string"); --- 940,990 ---- cmd = command_find(replacer); p++; } + + /* Set up commandraw for future use. This will contain the canonicalization + * of the command name and may later have the parsed rest of the input + * appended at the position pointed to by c2. + */ + c2 = c; + if (!cmd) { + c2 = commandraw + strlen(commandraw); + } else { + if (replacer) { + /* These commands don't allow switches, and need a space + * added after their canonical name + */ + c2 = commandraw; + safe_str(cmd->name, commandraw, &c2); + safe_chr(' ', commandraw, &c2); + } else if (*c2 == '/') { + /* Oh... DAMN */ + c2 = commandraw; + strcpy(switches, commandraw); + safe_str(cmd->name, commandraw, &c2); + t = strchr(switches, '/'); + safe_str(t, commandraw, &c2); + } else { + c2 = commandraw; + safe_str(cmd->name, commandraw, &c2); + } + } + /* Test if this either isn't a command, or is a disabled one * If so, return Fully Parsed string for further processing. */ if (!cmd || (cmd->type & CMD_T_DISABLED)) { if (*p) { if (*p == ' ') { ! safe_chr(' ', commandraw, &c2); p++; } ! process_expression(commandraw, &c2, (const char **) &p, player, cause, ! cause, noevtoken ? PE_NOTHING : ! ((PE_DEFAULT & ~PE_FUNCTION_CHECK) | ! PE_COMMAND_BRACES), PT_DEFAULT, NULL); } ! *c2 = '\0'; mush_free((Malloc_t) command, "string"); mush_free((Malloc_t) swtch, "string"); mush_free((Malloc_t) ls, "string"); *************** *** 1024,1029 **** --- 1046,1052 ---- else if (!*swp) swp = NULL; + strcpy(command2, p); if (*p == ' ') p++; ap = p; *************** *** 1043,1049 **** command_argparse(player, cause, &p, rs, rsa, cmd, 1, 1); SW_SET(sw, SWITCH_NOEVAL); /* Needed for ATTRIB_SET */ } else { ! noeval = SW_ISSET(sw, SWITCH_NOEVAL); if (cmd->type & CMD_T_EQSPLIT) { char *savep = p; command_argparse(player, cause, &p, ls, lsa, cmd, 0, noeval); --- 1066,1072 ---- command_argparse(player, cause, &p, rs, rsa, cmd, 1, 1); SW_SET(sw, SWITCH_NOEVAL); /* Needed for ATTRIB_SET */ } else { ! noeval = SW_ISSET(sw, SWITCH_NOEVAL) || noevtoken; if (cmd->type & CMD_T_EQSPLIT) { char *savep = p; command_argparse(player, cause, &p, ls, lsa, cmd, 0, noeval); *************** *** 1058,1074 **** } } if (cmd->func == NULL) { do_rawlog(LT_ERR, T("No command vector on command %s."), cmd->name); } else { char *saveregs[NUMQ] = { NULL }; ! run_hook(player, cause, &cmd->hooks.before, saveregs, 1); ! cmd->func(cmd, player, cause, sw, string, swp, ap, ls, lsa, rs, rsa); ! run_hook(player, cause, &cmd->hooks.after, saveregs, 0); ! if (cmd->type & CMD_T_LOGARGS) ! do_log(LT_CMD, player, cause, "%s", string); ! else if (cmd->type & CMD_T_LOGNAME) ! do_log(LT_CMD, player, cause, "%s", commandraw); } mush_free((Malloc_t) command, "string"); --- 1081,1128 ---- } } + + /* Finish setting up commandraw, if we may need it for hooks */ + if (has_hook(&cmd->hooks.ignore) || has_hook(&cmd->hooks.override)) { + p = command2; + if (*p) { + if (*p == ' ') { + safe_chr(' ', commandraw, &c2); + p++; + } + process_expression(commandraw, &c2, (const char **) &p, player, cause, + cause, noevtoken ? PE_NOTHING : + ((PE_DEFAULT & ~PE_FUNCTION_CHECK) | + PE_COMMAND_BRACES), PT_DEFAULT, NULL); + } + *c2 = '\0'; + } + + retval = NULL; if (cmd->func == NULL) { do_rawlog(LT_ERR, T("No command vector on command %s."), cmd->name); + return NULL; } else { char *saveregs[NUMQ] = { NULL }; ! /* If we have a hook/ignore that returns false, we don't do the command */ ! if (run_hook(player, cause, &cmd->hooks.ignore, saveregs, 1)) { ! /* If we have a hook/override, we use that instead */ ! if (!has_hook(&cmd->hooks.override) || ! !one_comm_match(cmd->hooks.override.obj, player, ! cmd->hooks.override.attrname, commandraw)) { ! /* Otherwise, we do hook/before, the command, and hook/after */ ! run_hook(player, cause, &cmd->hooks.before, saveregs, 1); ! cmd->func(cmd, player, cause, sw, string, swp, ap, ls, lsa, rs, rsa); ! run_hook(player, cause, &cmd->hooks.after, saveregs, 0); ! } ! /* Either way, we might log */ ! if (cmd->type & CMD_T_LOGARGS) ! do_log(LT_CMD, player, cause, "%s", string); ! else if (cmd->type & CMD_T_LOGNAME) ! do_log(LT_CMD, player, cause, "%s", commandraw); ! } else { ! retval = commandraw; ! } } mush_free((Malloc_t) command, "string"); *************** *** 1076,1082 **** mush_free((Malloc_t) ls, "string"); mush_free((Malloc_t) rs, "string"); mush_free((Malloc_t) switches, "string"); ! return NULL; } /** Add a restriction to a command. --- 1130,1136 ---- mush_free((Malloc_t) ls, "string"); mush_free((Malloc_t) rs, "string"); mush_free((Malloc_t) switches, "string"); ! return retval; } /** Add a restriction to a command. *************** *** 1292,1297 **** --- 1346,1358 ---- if (GoodObject(command->hooks.after.obj)) notify_format(player, "@hook/after: #%d/%s", command->hooks.after.obj, command->hooks.after.attrname); + if (GoodObject(command->hooks.ignore.obj)) + notify_format(player, "@hook/ignore: #%d/%s", command->hooks.ignore.obj, + command->hooks.ignore.attrname); + if (GoodObject(command->hooks.override.obj)) + notify_format(player, "@hook/override: #%d/%s", + command->hooks.override.obj, + command->hooks.override.attrname); } } } *************** *** 1417,1431 **** return command_check(player, cmd); } ! /** Run a before or after command hook. * This function runs a hook before or after a command execution. * \param player the enactor. * \param cause dbref that caused command to execute. * \param hook pointer to the hook. * \param saveregs array to store a copy of the final q-registers. * \param save if true, use saveregs to store a ending q-registers. */ ! void run_hook(dbref player, dbref cause, struct hook_data *hook, char *saveregs[], int save) { --- 1478,1504 ---- return command_check(player, cmd); } ! static int ! has_hook(struct hook_data *hook) ! { ! if (!hook || !GoodObject(hook->obj) || IsGarbage(hook->obj) ! || !hook->attrname) ! return 0; ! return 1; ! } ! ! ! /** Run a command hook. * This function runs a hook before or after a command execution. * \param player the enactor. * \param cause dbref that caused command to execute. * \param hook pointer to the hook. * \param saveregs array to store a copy of the final q-registers. * \param save if true, use saveregs to store a ending q-registers. + * \retval 1 Hook doesn't exist, or evaluates to a non-false value + * \retval 0 Hook exists and evaluates to a false value */ ! int run_hook(dbref player, dbref cause, struct hook_data *hook, char *saveregs[], int save) { *************** *** 1435,1452 **** char buff[BUFFER_LEN], *bp; char *origregs[NUMQ]; ! if (!hook || !GoodObject(hook->obj) || IsGarbage(hook->obj) ! || !hook->attrname) ! return; atr = atr_get(hook->obj, hook->attrname); if (!atr) ! return; code = safe_atr_value(atr); if (!code) ! return; #ifdef MEM_CHECK add_check("hook.code"); #endif --- 1508,1524 ---- char buff[BUFFER_LEN], *bp; char *origregs[NUMQ]; ! if (!has_hook(hook)) ! return 1; atr = atr_get(hook->obj, hook->attrname); if (!atr) ! return 1; code = safe_atr_value(atr); if (!code) ! return 1; #ifdef MEM_CHECK add_check("hook.code"); #endif *************** *** 1459,1470 **** --- 1531,1544 ---- process_expression(buff, &bp, &cp, hook->obj, cause, player, PE_DEFAULT, PT_DEFAULT, NULL); + *bp = '\0'; if (save) save_global_regs("hook.regs", saveregs); restore_global_regs("run_hook", origregs); mush_free(code, "hook.code"); + return parse_boolean(buff); } /** Set up or remove a command hook. *************** *** 1476,1487 **** * \param command command to hook. * \param obj name of object containing the hook attribute. * \param attrname of hook attribute on obj. ! * \param hook_type 1 (before) or 2 (after). */ void ! do_hook(dbref player, char *command, char *obj, char *attrname, int hook_type) { COMMAND_INFO *cmd; cmd = command_find(command); if (!cmd) { --- 1550,1563 ---- * \param command command to hook. * \param obj name of object containing the hook attribute. * \param attrname of hook attribute on obj. ! * \param flag type of hook */ void ! do_hook(dbref player, char *command, char *obj, char *attrname, ! enum hook_type flag) { COMMAND_INFO *cmd; + struct hook_data *h; cmd = command_find(command); if (!cmd) { *************** *** 1493,1508 **** return; } if (!obj && !attrname) { - struct hook_data *h; - if (hook_type == 1) - h = &cmd->hooks.before; - else if (hook_type == 2) - h = &cmd->hooks.after; - else { - notify(player, T("Unknown hook type")); - return; - } notify_format(player, T("Hook removed from %s."), cmd->name); h->obj = NOTHING; mush_free(h->attrname, "hook.attr"); --- 1569,1588 ---- return; } + if (flag == HOOK_BEFORE) + h = &cmd->hooks.before; + else if (flag == HOOK_AFTER) + h = &cmd->hooks.after; + else if (flag == HOOK_IGNORE) + h = &cmd->hooks.ignore; + else if (flag == HOOK_OVERRIDE) + h = &cmd->hooks.override; + else { + notify(player, T("Unknown hook type")); + return; + } + if (!obj && !attrname) { notify_format(player, T("Hook removed from %s."), cmd->name); h->obj = NOTHING; mush_free(h->attrname, "hook.attr"); *************** *** 1511,1525 **** notify(player, T("You must give both an object and attribute.")); } else { dbref objdb = match_thing(player, obj); ! struct hook_data *h; ! if (!GoodObject(objdb)) ! return; ! if (hook_type == 1) ! h = &cmd->hooks.before; ! else if (hook_type == 2) ! h = &cmd->hooks.after; ! else { ! notify(player, T("Unknown hook type")); return; } h->obj = objdb; --- 1591,1598 ---- notify(player, T("You must give both an object and attribute.")); } else { dbref objdb = match_thing(player, obj); ! if (!GoodObject(objdb)) { ! notify(player, T("Invalid hook object.")); return; } h->obj = objdb; *** 1_7_7.561/src/cmds.c Mon, 18 Aug 2003 20:59:29 -0500 dunemush (pennmush/c/37_cmds.c 1.33.1.1.1.2.1.2.2.3.1.1.1.2.1.1.1.3.1.8.1.1.2.2.2.20 660) --- 1_7_7.623(w)/src/cmds.c Wed, 10 Sep 2003 14:47:25 -0500 dunemush (pennmush/c/37_cmds.c 1.33.1.1.1.2.1.2.2.3.1.1.1.2.1.1.1.3.1.8.1.1.2.2.2.20.1.3 660) *************** *** 52,59 **** /** Is there a right-hand side of the equal sign? From command.c */ extern int rhs_present; - void do_hook(dbref player, char *command, char *obj, char *attrname, - int hook_type); COMMAND (cmd_allhalt) { do_allhalt(player); --- 52,57 ---- *************** *** 359,365 **** } COMMAND (cmd_hook) { ! int hook_type = 0; if (!Wizard(player)) { notify(player, T("You need a fishing license to use that hook.")); --- 357,363 ---- } COMMAND (cmd_hook) { ! enum hook_type flags; if (!Wizard(player)) { notify(player, T("You need a fishing license to use that hook.")); *************** *** 367,380 **** } if (SW_ISSET(sw, SWITCH_AFTER)) ! hook_type = 2; else if (SW_ISSET(sw, SWITCH_BEFORE)) ! hook_type = 1; else { notify(player, T("You must give a switch for @hook")); return; } ! do_hook(player, arg_left, args_right[1], args_right[2], hook_type); } COMMAND (cmd_kick) { --- 365,382 ---- } if (SW_ISSET(sw, SWITCH_AFTER)) ! flags = HOOK_AFTER; else if (SW_ISSET(sw, SWITCH_BEFORE)) ! flags = HOOK_BEFORE; ! else if (SW_ISSET(sw, SWITCH_IGNORE)) ! flags = HOOK_IGNORE; ! else if (SW_ISSET(sw, SWITCH_OVERRIDE)) ! flags = HOOK_OVERRIDE; else { notify(player, T("You must give a switch for @hook")); return; } ! do_hook(player, arg_left, args_right[1], args_right[2], flags); } COMMAND (cmd_kick) { *** 1_7_7.561/src/bsd.c Wed, 20 Aug 2003 00:25:24 -0500 dunemush (pennmush/c/38_bsd.c 1.58.1.11.1.2.1.5.1.7.1.14.1.13.1.9.1.4.1.2.1.12.1.1.1.1.1.2.1.1.1.13.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.8.2.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.22 660) --- 1_7_7.623(w)/src/bsd.c Wed, 10 Sep 2003 14:47:25 -0500 dunemush (pennmush/c/38_bsd.c 1.58.1.11.1.2.1.5.1.7.1.14.1.13.1.9.1.4.1.2.1.12.1.1.1.1.1.2.1.1.1.13.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.8.2.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.24.1.8.1.2 660) *************** *** 190,195 **** --- 190,197 ---- #define CONN_TELNET 0x2 /** Send a telnet option to test client */ #define CONN_TELNET_QUERY 0x4 + /** Connection that should be close on load from reboot.db */ + #define CONN_CLOSE_READY 0x8 /** Is this descriptor connected to a telnet-compatible terminal? */ #define TELNET_ABLE(d) ((d)->conn_flags & (CONN_TELNET | CONN_TELNET_QUERY)) *************** *** 401,406 **** --- 403,409 ---- static void set_userstring(unsigned char **userstring, const char *command); static void process_commands(void); static int do_command(DESC *d, char *command); + static void parse_puebloclient(DESC *d, char *command); static int dump_messages(DESC *d, dbref player, int new); static int check_connect(DESC *d, const char *msg); static void parse_connect(const char *msg, char *command, char *user, *************** *** 1349,1355 **** } if (d->conn_flags & CONN_HTML) { if (fb[1].buff) ! queue_write(d, fb[1].buff, fb[1].len); else queue_write(d, fb[0].buff, fb[0].len); } else --- 1352,1358 ---- } if (d->conn_flags & CONN_HTML) { if (fb[1].buff) ! queue_newwrite(d, fb[1].buff, fb[1].len); else queue_write(d, fb[0].buff, fb[0].len); } else *************** *** 1639,1646 **** d->next->prev = d->prev; #ifdef HAS_OPENSSL ! if (sslsock && d->ssl) ssl_close_connection(d->ssl); #endif #ifdef NT_TCP --- 1642,1651 ---- d->next->prev = d->prev; #ifdef HAS_OPENSSL ! if (sslsock && d->ssl) { ssl_close_connection(d->ssl); + d->ssl = NULL; + } #endif #ifdef NT_TCP *************** *** 1700,1705 **** --- 1705,1711 ---- d->width = 78; d->height = 24; d->ttype = mush_strdup("unknown", "terminal description"); + d->checksum[0] = '\0'; #ifdef HAS_OPENSSL d->ssl = NULL; d->ssl_state = 0; *************** *** 2492,2498 **** pend = d->raw_input + MAX_COMMAND_LEN - 1; for (q = (unsigned char *) tbuf1, qend = (unsigned char *) tbuf1 + got; q < qend; q++) { ! if (*q == '\n') { *p = '\0'; if (p > d->raw_input) save_command(d, d->raw_input); --- 2498,2514 ---- pend = d->raw_input + MAX_COMMAND_LEN - 1; for (q = (unsigned char *) tbuf1, qend = (unsigned char *) tbuf1 + got; q < qend; q++) { ! if (*q == '\r') { ! /* A broken client (read: WinXP telnet) might send only CR, and not CRLF ! * so it's nice of us to try to handle this. ! */ ! *p = '\0'; ! if (p > d->raw_input) ! save_command(d, d->raw_input); ! p = d->raw_input; ! if (((q + 1) < qend) && (*(q + 1) == '\n')) ! q++; /* For clients that work */ ! } else if (*q == '\n') { *p = '\0'; if (p > d->raw_input) save_command(d, d->raw_input); *************** *** 2519,2526 **** d->raw_input = 0; d->raw_input_at = 0; } - - } /* ARGSUSED */ --- 2535,2540 ---- *************** *** 2706,2713 **** --- 2720,2729 ---- d->height = parse_integer(command + 12); } else if (SUPPORT_PUEBLO && !strncmp(command, PUEBLO_COMMAND, strlen(PUEBLO_COMMAND))) { + parse_puebloclient(d, command); if (!(d->conn_flags & CONN_HTML)) { queue_newwrite(d, (unsigned char *) PUEBLO_SEND, strlen(PUEBLO_SEND)); + process_output(d); do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Switching to Pueblo mode."), d->descriptor, d->addr, d->ip); d->conn_flags |= CONN_HTML; *************** *** 2738,2743 **** --- 2754,2776 ---- return 1; } + static void + parse_puebloclient(DESC *d, char *command) + { + const char *p, *end; + if ((p = string_match(command, "md5="))) { + /* Skip md5=" */ + p += 5; + if ((end = strchr(p, '"'))) { + if ((end > p) && ((end - p) <= PUEBLO_CHECKSUM_LEN)) { + /* Got it! */ + strncpy(d->checksum, p, end - p); + d->checksum[end - p] = '\0'; + } + } + } + } + static int dump_messages(DESC *d, dbref player, int isnew) { *************** *** 4540,4562 **** void close_ssl_connections(void) { ! DESC *d, *dnext; if (!sslsock) return; /* Close clients */ ! for (d = descriptor_list; d; d = dnext) { ! dnext = d->next; if (d->ssl) { queue_string_eol(d, T(ssl_shutdown_message)); ! shutdownsock(d); } } - /* Make sure everyone sees their disconnect messages, too */ - DESC_ITER_CONN(d) { - process_output(d); - } /* Close server socket */ ssl_close_connection(ssl_master_socket); shutdown(sslsock, 2); --- 4573,4593 ---- void close_ssl_connections(void) { ! DESC *d; if (!sslsock) return; /* Close clients */ ! DESC_ITER_CONN(d) { if (d->ssl) { queue_string_eol(d, T(ssl_shutdown_message)); ! process_output(d); ! ssl_close_connection(d->ssl); ! d->ssl = NULL; ! d->conn_flags |= CONN_CLOSE_READY; } } /* Close server socket */ ssl_close_connection(ssl_master_socket); shutdown(sslsock, 2); *************** *** 4576,4582 **** { FILE *f; DESC *d; ! long flags = RDBF_SCREENSIZE | RDBF_TTYPE; if (setjmp(db_err)) { flag_broadcast(0, 0, T("GAME: Error writing reboot database!")); exit(0); --- 4607,4613 ---- { FILE *f; DESC *d; ! long flags = RDBF_SCREENSIZE | RDBF_TTYPE | RDBF_PUEBLO_CHECKSUM; if (setjmp(db_err)) { flag_broadcast(0, 0, T("GAME: Error writing reboot database!")); exit(0); *************** *** 4624,4629 **** --- 4655,4661 ---- putref(f, d->width); putref(f, d->height); putstring(f, d->ttype); + putstring(f, d->checksum); } /* for loop */ putref(f, 0); *************** *** 4641,4646 **** --- 4673,4679 ---- { FILE *f; DESC *d = NULL; + DESC *closed = NULL, *nextclosed; int val; const char *temp; char c; *************** *** 4698,4703 **** --- 4731,4740 ---- d->ttype = mush_strdup(getstring_noalloc(f), "terminal description"); else d->ttype = mush_strdup("unknown", "terminal description"); + if (flags & RDBF_PUEBLO_CHECKSUM) + strcpy(d->checksum, getstring_noalloc(f)); + else + d->checksum[0] = '\0'; d->input_chars = 0; d->output_chars = 0; d->output_size = 0; *************** *** 4715,4734 **** d->ssl = NULL; d->ssl_state = 0; #endif ! if (descriptor_list) ! descriptor_list->prev = d; ! d->next = descriptor_list; ! d->prev = NULL; ! descriptor_list = d; ! if (d->connected && d->player && GoodObject(d->player) && ! IsPlayer(d->player)) ! set_flag_internal(d->player, "CONNECTED"); ! else if ((!d->player || !GoodObject(d->player)) && d->connected) { ! d->connected = 0; ! d->player = 0; } } /* while loop */ strcpy(poll_msg, getstring_noalloc(f)); first_start_time = getref(f); reboot_count = getref(f) + 1; --- 4752,4792 ---- d->ssl = NULL; d->ssl_state = 0; #endif ! if (d->conn_flags & CONN_CLOSE_READY) { ! /* This isn't really an open descriptor, we're just tracking ! * it so we can announce the disconnect properly. Do so, but ! * don't link it into the descriptor list. Instead, keep a ! * separate list. ! */ ! if (closed) ! closed->prev = d; ! d->next = closed; ! d->prev = NULL; ! closed = d; ! } else { ! if (descriptor_list) ! descriptor_list->prev = d; ! d->next = descriptor_list; ! d->prev = NULL; ! descriptor_list = d; ! if (d->connected && d->player && GoodObject(d->player) && ! IsPlayer(d->player)) ! set_flag_internal(d->player, "CONNECTED"); ! else if ((!d->player || !GoodObject(d->player)) && d->connected) { ! d->connected = 0; ! d->player = 0; ! } } } /* while loop */ + /* Now announce disconnects of everyone who's not really here */ + while (closed) { + nextclosed = closed->next; + announce_disconnect(closed->player); + mush_free(closed, "descriptor"); + closed = nextclosed; + } + strcpy(poll_msg, getstring_noalloc(f)); first_start_time = getref(f); reboot_count = getref(f) + 1; *** 1_7_7.561/src/attrib.c Tue, 19 Aug 2003 17:32:23 -0500 dunemush (pennmush/c/40_attrib.c 1.15.1.2.1.5.1.1.1.3.1.3.1.2.1.2.1.2.2.1.1.2.1.2.1.2.1.1.1.3.1.1.1.1.1.1.3.24 660) --- 1_7_7.623(w)/src/attrib.c Wed, 10 Sep 2003 14:47:25 -0500 dunemush (pennmush/c/40_attrib.c 1.15.1.2.1.5.1.1.1.3.1.3.1.2.1.2.1.2.2.1.1.2.1.2.1.2.1.1.1.3.1.1.1.1.1.1.3.29 660) *************** *** 697,706 **** /* check for lots of easy ways out */ if ((type != '$' && type != '^') || !GoodObject(thing) || Halted(thing) ! || (type == '$' ! && (NoCommand(thing) || !eval_lock(player, thing, Command_Lock))) ! || (type == '^' && !eval_lock(player, thing, Listen_Lock)) ! || !eval_lock(player, thing, Use_Lock)) return 0; if (type == '$') { --- 697,703 ---- /* check for lots of easy ways out */ if ((type != '$' && type != '^') || !GoodObject(thing) || Halted(thing) ! || (type == '$' && NoCommand(thing))) return 0; if (type == '$') { *************** *** 758,763 **** --- 755,766 ---- } } if (match_found) { + if ((type == '$' && !eval_lock(player, thing, Command_Lock)) + || (type == '^' && !eval_lock(player, thing, Listen_Lock)) + || !eval_lock(player, thing, Use_Lock)) { + match--; + continue; + } if (atrname && abp) { safe_chr(' ', atrname, abp); safe_dbref(thing, atrname, abp); *************** *** 817,822 **** --- 820,831 ---- } } if (match_found) { + if ((type == '$' && !eval_lock(player, thing, Command_Lock)) + || (type == '^' && !eval_lock(player, thing, Listen_Lock)) + || !eval_lock(player, thing, Use_Lock)) { + match--; + continue; + } if (atrname && abp) { safe_chr(' ', atrname, abp); safe_dbref(thing, atrname, abp); *************** *** 832,837 **** --- 841,907 ---- return match; } + /** Match input against a specified object's specified $command + * attribute. Matches may be glob or regex matches. Used in command hooks. + * depending on the attribute's flags. + * \param thing object containing attributes to check. + * \param player the enactor, for privilege checks. + * \param atr the name of the attribute + * \param str the string to match + * \retval 1 attribute matched. + * \retval 0 attribute failed to match. + */ + int + one_comm_match(dbref thing, dbref player, const char *atr, const char *str) + { + ATTR *ptr; + char tbuf1[BUFFER_LEN]; + char tbuf2[BUFFER_LEN]; + char *s; + + /* check for lots of easy ways out */ + if (!GoodObject(thing) || Halted(thing) || NoCommand(thing)) + return 0; + + if (!(ptr = atr_get(thing, atr))) + return 0; + + if ((AL_FLAGS(ptr) & AF_NOPROG) || !(AL_FLAGS(ptr) & AF_COMMAND)) + return 0; + + strcpy(tbuf1, atr_value(ptr)); + s = tbuf1; + do { + s = strchr(s + 1, ':'); + } while (s && s[-1] == '\\'); + if (!s) + return 0; + *s++ = '\0'; + + if (AL_FLAGS(ptr) & AF_REGEXP) { + /* Turn \: into : */ + char *from, *to; + for (from = tbuf1, to = tbuf2; *from; from++, to++) { + if (*from == '\\' && *(from + 1) == ':') + from++; + *to = *from; + } + *to = '\0'; + } else + strcpy(tbuf2, tbuf1); + + if ((AL_FLAGS(ptr) & AF_REGEXP) ? + regexp_match_case(tbuf2 + 1, str, AL_FLAGS(ptr) & AF_CASE) : + wild_match_case(tbuf2 + 1, str, AL_FLAGS(ptr) & AF_CASE)) { + if (!eval_lock(player, thing, Command_Lock) + || !eval_lock(player, thing, Use_Lock)) + return 0; + parse_que(thing, s, player); + return 1; + } + return 0; + } + /*======================================================================*/ /** Set or clear an attribute on an object. *************** *** 881,887 **** if (old) { /* Old alias - we're allowed to change to a different case */ strcpy(tbuf1, atr_value(old)); ! if (s && (!*s || (strcasecmp(s, tbuf1) && !ok_player_name(s)))) { notify(player, T("That is not a valid alias.")); return -1; } --- 951,957 ---- if (old) { /* Old alias - we're allowed to change to a different case */ strcpy(tbuf1, atr_value(old)); ! if (s && (!*s || (strcasecmp(s, tbuf1) && !ok_player_name(s, player)))) { notify(player, T("That is not a valid alias.")); return -1; } *************** *** 889,900 **** delete_player(thing, tbuf1); } else { /* No old alias */ ! if (s && *s && !ok_player_name(s)) { notify(player, T("That is not a valid alias.")); return -1; } } ! } else if (s && *s && !strcmp(name, "FORWARDLIST")) { /* You can only set this to dbrefs of things you're allowed to * forward to. If you get one wrong, we puke. */ --- 959,971 ---- delete_player(thing, tbuf1); } else { /* No old alias */ ! if (s && *s && !ok_player_name(s, player)) { notify(player, T("That is not a valid alias.")); return -1; } } ! } else if (s && *s && (!strcmp(name, "FORWARDLIST") ! || !strcmp(name, "DEBUGFORWARDLIST"))) { /* You can only set this to dbrefs of things you're allowed to * forward to. If you get one wrong, we puke. */ *************** *** 904,915 **** fwdstr = trim_space_sep(tbuf1, ' '); while ((curr = split_token(&fwdstr, ' ')) != NULL) { if (!is_dbref(curr)) { ! notify(player, T("@forwardlist should contain only dbrefs.")); return -1; } fwd = parse_dbref(curr); if (!GoodObject(fwd) || IsGarbage(fwd)) { ! notify_format(player, T("Invalid dbref #%d in @forwardlist."), fwd); return -1; } if (!Can_Forward(thing, fwd)) { --- 975,986 ---- fwdstr = trim_space_sep(tbuf1, ' '); while ((curr = split_token(&fwdstr, ' ')) != NULL) { if (!is_dbref(curr)) { ! notify_format(player, T("%s should contain only dbrefs."), name); return -1; } fwd = parse_dbref(curr); if (!GoodObject(fwd) || IsGarbage(fwd)) { ! notify_format(player, T("Invalid dbref #%d in %s."), fwd, name); return -1; } if (!Can_Forward(thing, fwd)) { *** 1_7_7.561/hdrs/version.h Wed, 20 Aug 2003 01:05:31 -0500 dunemush (pennmush/c/47_version.h 1.32.1.2.1.7.1.9.1.1.1.17.1.23 660) --- 1_7_7.623(w)/hdrs/version.h Wed, 10 Sep 2003 14:47:30 -0500 dunemush (pennmush/c/47_version.h 1.32.1.2.1.7.1.9.1.1.1.17.1.24 660) *************** *** 1,3 **** ! #define VERSION "PennMUSH version 1.7.7 patchlevel 19 [08/19/2003]" ! #define SHORTVN "PennMUSH 1.7.7p19" ! #define NUMVERSION 001007007019 --- 1,3 ---- ! #define VERSION "PennMUSH version 1.7.7 patchlevel 20 [09/04/2003]" ! #define SHORTVN "PennMUSH 1.7.7p20" ! #define NUMVERSION 001007007020 *** 1_7_7.561/hdrs/mushdb.h Mon, 11 Aug 2003 13:09:23 -0500 dunemush (pennmush/d/2_mushdb.h 1.1.1.9.1.1.1.14 660) --- 1_7_7.623(w)/hdrs/mushdb.h Wed, 10 Sep 2003 14:47:30 -0500 dunemush (pennmush/d/2_mushdb.h 1.1.1.9.1.1.1.16 660) *************** *** 6,11 **** --- 6,12 ---- #define __DB_H /* Power macros */ + #include "flags.h" #define Builder(x) (command_check_byname(x, "@dig")) #define Guest(x) (Powers(x) & IS_GUEST) *************** *** 157,161 **** --- 158,163 ---- */ #define RDBF_SCREENSIZE 0x01 #define RDBF_TTYPE 0x02 + #define RDBF_PUEBLO_CHECKSUM 0x04 #endif /* __DB_H */ *** 1_7_7.561/hdrs/lock.h Sat, 05 Jul 2003 15:56:20 -0500 dunemush (pennmush/d/6_lock.h 1.19 660) --- 1_7_7.623(w)/hdrs/lock.h Wed, 10 Sep 2003 14:47:30 -0500 dunemush (pennmush/d/6_lock.h 1.20 660) *************** *** 102,107 **** --- 102,108 ---- extern const lock_type Control_Lock; /* Who can control this object? */ extern const lock_type Dropto_Lock; /* Who follows the dropto of this room? */ extern const lock_type Destroy_Lock; /* Who can @dest me if I'm dest_ok? */ + extern const lock_type Interact_Lock; /* Declare new lock types here! */ #endif /* __LOCK_H */ *** 1_7_7.561/hdrs/game.h Mon, 18 Aug 2003 20:59:29 -0500 dunemush (pennmush/d/12_game.h 1.28.1.2.1.1.1.1.1.1.1.7.1.6 660) --- 1_7_7.623(w)/hdrs/game.h Wed, 10 Sep 2003 14:47:30 -0500 dunemush (pennmush/d/12_game.h 1.28.1.2.1.1.1.1.1.1.1.7.1.9 660) *************** *** 38,43 **** --- 38,49 ---- extern void do_restart(void); extern void do_restart_com(dbref player, const char *arg1); + /* From command.c */ + enum hook_type { HOOK_BEFORE, HOOK_AFTER, HOOK_IGNORE, HOOK_OVERRIDE }; + extern void do_hook(dbref player, char *command, char *obj, char *attrname, + enum hook_type flag); + + /* From compress.c */ #if (COMPRESSION_TYPE > 0) extern int init_compress(FILE * f); *** 1_7_7.561/hdrs/externs.h Tue, 19 Aug 2003 12:07:25 -0500 dunemush (pennmush/d/16_externs.h 1.1.1.53.1.2.1.8.2.1.1.2.1.1.1.1.1.2.1.6.1.3.1.4.3.1.1.1.1.13 660) --- 1_7_7.623(w)/hdrs/externs.h Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/d/16_externs.h 1.1.1.53.1.2.1.8.2.1.1.2.1.1.1.1.1.2.1.6.1.3.1.4.3.1.1.1.1.18 660) *************** *** 50,55 **** --- 50,57 ---- __attribute__ ((__format__(__printf__, 3, 4))); extern void raw_notify(dbref player, const char *msg); + extern void notify_list(dbref speaker, dbref thing, const char *atr, + const char *msg, int flags); extern dbref short_page(const char *match); extern dbref visible_short_page(dbref player, const char *match); extern void do_doing(dbref player, const char *message); *************** *** 99,104 **** --- 101,109 ---- #define NA_INTER_HEAR 0x0200 /* Message is auditory in nature */ #define NA_INTER_SEE 0x0400 /* Message is visual in nature */ #define NA_INTER_PRESENCE 0x0800 /* Message is about presence */ + #define NA_NOSPOOF 0x1000 /* Message comes via a NO_SPOOF object. */ + #define NA_PARANOID 0x2000 /* Message comes via a PARANOID object. */ + #define NA_NOPREFIX 0x4000 /* Don't use @prefix when forwarding */ #define NA_INTERACTION (NA_INTER_HEAR|NA_INTER_SEE|NA_INTER_PRESENCE) /* Message follows interaction rules */ /** A notify_anything lookup function type definition */ *************** *** 265,271 **** #endif extern int ok_name(const char *name); extern int ok_command_name(const char *name); ! extern int ok_player_name(const char *name); extern int ok_password(const char *password); extern dbref parse_match_possessive(dbref player, const char *str); extern void page_return(dbref player, dbref target, const char *type, --- 270,276 ---- #endif extern int ok_name(const char *name); extern int ok_command_name(const char *name); ! extern int ok_player_name(const char *name, dbref player); extern int ok_password(const char *password); extern dbref parse_match_possessive(dbref player, const char *str); extern void page_return(dbref player, dbref target, const char *type, *** 1_7_7.561/hdrs/extchat.h Wed, 02 Jul 2003 14:19:13 -0500 dunemush (pennmush/d/17_extchat.h 1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.3.1.1.1.1.2.2.1.9 660) --- 1_7_7.623(w)/hdrs/extchat.h Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/d/17_extchat.h 1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.3.1.1.1.1.2.2.1.9.1.1 660) *************** *** 64,69 **** --- 64,74 ---- #define CU_GAG 0x4 /* Do not hear any messages */ #define CU_DEFAULT_FLAGS 0x0 + /* channel_broadcast flags */ + #define CB_CHECKQUIET 0x1 /* Check for quiet flag on recipients */ + #define CB_NOSPOOF 0x2 /* Use nospoof emits */ + #define CB_PRESENCE 0x4 /* This is a presence message, not sound */ + #define CUdbref(u) ((u)->who) #define CUtype(u) ((u)->type) #define CUtitle(u) ((u)->title) *** 1_7_7.561/hdrs/dbdefs.h Thu, 17 Jul 2003 15:25:22 -0500 dunemush (pennmush/d/18_dbdefs.h 1.1.1.1.1.1.1.1.1.1.1.2.2.2.1.1.1.1.1.1.2.1.1.21 660) --- 1_7_7.623(w)/hdrs/dbdefs.h Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/d/18_dbdefs.h 1.1.1.1.1.1.1.1.1.1.1.2.2.2.1.1.1.1.1.1.2.1.1.22 660) *************** *** 94,101 **** #define Terse(x) (IS(Owner(x), TYPE_PLAYER, "TERSE") || IS(x, TYPE_THING, "TERSE")) #define Myopic(x) (IS(Owner(x), TYPE_PLAYER, "MYOPIC")) ! #define Nospoof(x) (IS(Owner(x), TYPE_PLAYER, "NOSPOOF")) ! #define Paranoid(x) (IS(Owner(x), TYPE_PLAYER, "PARANOID")) #define Gagged(x) (IS(Owner(x), TYPE_PLAYER, "GAGGED")) #define ShowAnsi(x) (IS(Owner(x), TYPE_PLAYER, "ANSI")) #define ShowAnsiColor(x) (IS(Owner(x), TYPE_PLAYER, "COLOR")) --- 94,101 ---- #define Terse(x) (IS(Owner(x), TYPE_PLAYER, "TERSE") || IS(x, TYPE_THING, "TERSE")) #define Myopic(x) (IS(Owner(x), TYPE_PLAYER, "MYOPIC")) ! #define Nospoof(x) (IS(Owner(x),TYPE_PLAYER,"NOSPOOF") || has_flag_by_name(x,"NOSPOOF",NOTYPE)) ! #define Paranoid(x) (IS(Owner(x),TYPE_PLAYER,"PARANOID") || has_flag_by_name(x,"PARANOID",NOTYPE)) #define Gagged(x) (IS(Owner(x), TYPE_PLAYER, "GAGGED")) #define ShowAnsi(x) (IS(Owner(x), TYPE_PLAYER, "ANSI")) #define ShowAnsiColor(x) (IS(Owner(x), TYPE_PLAYER, "COLOR")) *** 1_7_7.561/hdrs/conf.h Sun, 17 Aug 2003 08:30:54 -0500 dunemush (pennmush/d/20_conf.h 1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.5.1.1.1.1.1.1.1.1.1.2.1.1.2.1.2.13.1.4.1.18 660) --- 1_7_7.623(w)/hdrs/conf.h Wed, 10 Sep 2003 14:47:29 -0500 dunemush (pennmush/d/20_conf.h 1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.5.1.1.1.1.1.1.1.1.1.2.1.1.2.1.2.13.1.4.1.20 660) *************** *** 33,38 **** --- 33,39 ---- #define SEMI_POSE_TOKEN ';' #define EMIT_TOKEN '\\' #define CHAT_TOKEN '+' + #define NOEVAL_TOKEN ']' /* delimiter for lists of exit aliases */ #define EXIT_DELIMITER ';' *************** *** 51,58 **** #define PUEBLO_COMMAND "PUEBLOCLIENT " /* These CAN be modified, but it's heavily NOT suggested */ ! #define PUEBLO_SEND "\n" ! #define PUEBLO_HELLO "This world is Pueblo 1.10 Enhanced.\r\n" #define MAX_OUTPUT 16384 --- 52,59 ---- #define PUEBLO_COMMAND "PUEBLOCLIENT " /* These CAN be modified, but it's heavily NOT suggested */ ! #define PUEBLO_SEND "\n" ! #define PUEBLO_HELLO "This world is Pueblo 2.50 Enhanced.\r\n" #define MAX_OUTPUT 16384 *** 1_7_7.561/hdrs/switches.h Sat, 31 May 2003 16:38:17 -0500 dunemush (pennmush/d/21_switches.h 1.2.1.6.2.7.1.4 660) --- 1_7_7.623(w)/hdrs/switches.h Wed, 10 Sep 2003 14:47:30 -0500 dunemush (pennmush/d/21_switches.h 1.2.1.6.2.7.1.5 660) *************** *** 55,138 **** #define SWITCH_HEADER 54 #define SWITCH_HERE 55 #define SWITCH_HIDE 56 ! #define SWITCH_ILIST 57 ! #define SWITCH_INVENTORY 58 ! #define SWITCH_IPRINT 59 ! #define SWITCH_JOIN 60 ! #define SWITCH_LIST 61 ! #define SWITCH_LOWERCASE 62 ! #define SWITCH_ME 63 ! #define SWITCH_MEMBERS 64 ! #define SWITCH_MOD 65 ! #define SWITCH_MORTAL 66 ! #define SWITCH_MOTD 67 ! #define SWITCH_MUTE 68 ! #define SWITCH_NAME 69 ! #define SWITCH_NO 70 ! #define SWITCH_NOEVAL 71 ! #define SWITCH_NOFLAGCOPY 72 ! #define SWITCH_NOISY 73 ! #define SWITCH_NOSIG 74 ! #define SWITCH_NOSPACE 75 ! #define SWITCH_NOTIFY 76 ! #define SWITCH_NUKE 77 ! #define SWITCH_OFF 78 ! #define SWITCH_ON 79 ! #define SWITCH_OUTSIDE 80 ! #define SWITCH_OVERRIDE 81 ! #define SWITCH_PAGING 82 ! #define SWITCH_PANIC 83 ! #define SWITCH_PARANOID 84 ! #define SWITCH_PLAYERS 85 ! #define SWITCH_PORT 86 ! #define SWITCH_PRESERVE 87 ! #define SWITCH_PRINT 88 ! #define SWITCH_PRIVS 89 ! #define SWITCH_PURGE 90 ! #define SWITCH_QUICK 91 ! #define SWITCH_QUIET 92 ! #define SWITCH_READ 93 ! #define SWITCH_REBOOT 94 ! #define SWITCH_RECALL 95 ! #define SWITCH_REGIONS 96 ! #define SWITCH_REGISTER 97 ! #define SWITCH_REMOVE 98 ! #define SWITCH_RENAME 99 ! #define SWITCH_RESTORE 100 ! #define SWITCH_RESTRICT 101 ! #define SWITCH_RETROACTIVE 102 ! #define SWITCH_ROOM 103 ! #define SWITCH_ROOMS 104 ! #define SWITCH_SEE 105 ! #define SWITCH_SEEFLAG 106 ! #define SWITCH_SELF 107 ! #define SWITCH_SEND 108 ! #define SWITCH_SET 109 ! #define SWITCH_SILENT 110 ! #define SWITCH_SKIPDEFAULTS 111 ! #define SWITCH_SPEAK 112 ! #define SWITCH_STATS 113 ! #define SWITCH_SUMMARY 114 ! #define SWITCH_TABLES 115 ! #define SWITCH_TAG 116 ! #define SWITCH_TELEPORT 117 ! #define SWITCH_TF 118 ! #define SWITCH_THINGS 119 ! #define SWITCH_TITLE 120 ! #define SWITCH_TRACE 121 ! #define SWITCH_UNCLEAR 122 ! #define SWITCH_UNFOLDER 123 ! #define SWITCH_UNGAG 124 ! #define SWITCH_UNHIDE 125 ! #define SWITCH_UNMUTE 126 ! #define SWITCH_UNTAG 127 ! #define SWITCH_UNTIL 128 ! #define SWITCH_URGENT 129 ! #define SWITCH_USEFLAG 130 ! #define SWITCH_WHAT 131 ! #define SWITCH_WHO 132 ! #define SWITCH_WIPE 133 ! #define SWITCH_WIZ 134 ! #define SWITCH_WIZARD 135 ! #define SWITCH_YES 136 ! #define SWITCH_ZONE 137 --- 55,139 ---- #define SWITCH_HEADER 54 #define SWITCH_HERE 55 #define SWITCH_HIDE 56 ! #define SWITCH_IGNORE 57 ! #define SWITCH_ILIST 58 ! #define SWITCH_INVENTORY 59 ! #define SWITCH_IPRINT 60 ! #define SWITCH_JOIN 61 ! #define SWITCH_LIST 62 ! #define SWITCH_LOWERCASE 63 ! #define SWITCH_ME 64 ! #define SWITCH_MEMBERS 65 ! #define SWITCH_MOD 66 ! #define SWITCH_MORTAL 67 ! #define SWITCH_MOTD 68 ! #define SWITCH_MUTE 69 ! #define SWITCH_NAME 70 ! #define SWITCH_NO 71 ! #define SWITCH_NOEVAL 72 ! #define SWITCH_NOFLAGCOPY 73 ! #define SWITCH_NOISY 74 ! #define SWITCH_NOSIG 75 ! #define SWITCH_NOSPACE 76 ! #define SWITCH_NOTIFY 77 ! #define SWITCH_NU