-Configure
+autom4te.cache
+aclocal.m4
+configure
Makefile
-.config
-Obsolete
-Wanted
+config.log
+config.status
config.h
-config.sh
-config.sh.old
-config_h.SH
-confmagic.h
options.h
options.h.bak
+test/alltests.sh
+ src/cmdlocal.c
+ src/console
+ src/console~
+ src/flaglocal.c
+ src/funlocal.c
+ src/local.c
+ utils/mkcmds.sh
+ win32/cmds.h
+ win32/funs.h
+ win32/switches.h
hdrs/buildinf.h
hdrs/cmds.h
hdrs/funs.h
--- /dev/null
- CCFLAGS=@CFLAGS@ -I.. -I../hdrs @OPENSSL_INCLUDES@ @CPPFLAGS@ @PCRE_CFLAGS@ -Werror
+# Makefile for CobraMUSH
+
+# - System configuration - #
+
+VERSION=0.80
+PATCHLEVEL=0
+
+#
+# This section of the file should be automatically configured by
+# the Configure script. If it doesn't work, you might try starting
+# from the Makefile.old that's included instead, and reporting
+# your problem (including this Makefile) to pennmush-bugs@pennmush.org
+#
+# If you want to profile the code, add -pg -a -DPROFILING to CCFLAGS
+# and (probably) remove -O
+#
+MAKE=@MAKE@
+CC=@CC@
+
+SQL_CFLAGS=@MYSQL_CFLAGS@ @POSTGRESQL_CFLAGS@ @SQLITE3_CFLAGS@
+SQL_LDFLAGS=@MYSQL_LDFLAGS@ @POSTGRESQL_LDFLAGS@ @SQLITE3_LDFLAGS@
+LIBTOOL=@LIBTOOL@
+
+CPPFLAGS=@CPPFLAGS@
++CCFLAGS=@CFLAGS@ -I.. -I../hdrs @OPENSSL_INCLUDES@ @CPPFLAGS@ @PCRE_CFLAGS@ -Wall -Wno-comment -Wno-unused-but-set-variable -Werror
+LDFLAGS=@LDFLAGS@ @OPENSSL_INCLUDES@
+CLIBS=@LIBS@ @PCRE_LIBS@ @LIBLTDL@ @LIBLUA@ @OPENSSL_LIBS@
+INSTALL=@INSTALL@
+INSTALLDIR=$installdir
+CP=@CP@
+CHMOD=@CHMOD@
+INSTALL_LINKS=@LN_S@ ../src/netmud netmush; @LN_S@ ../src/info_slave info_slave
+
+# stupid SYS V shell
+SHELL=/bin/sh
+# Where to install with 'make globalinstall'
+GLOBAL_INSTALL=@libexecdir@
+
+all: config.h options.h autogen game/mush.cnf
+ @echo "Making all in src."
+ (cd src; @MAKE@ all "CC=$(CC)" "CCFLAGS=$(CCFLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" "CLIBS=$(CLIBS)" "MAKE=$(MAKE)" \
+ "MAKEFLAGS=$(MAKEFLAGS)" "SQL_CFLAGS=$(SQL_CFLAGS)" \
+ "SQL_LDFLAGS=$(SQL_LDFLAGS)")
+ @echo "If the make was successful, use 'make install' to install links."
+
+config.h: configure
+ @echo "Looks like your configure has been updated."
+ @echo "Run that first. If you did just run configure and"
+ @echo "it said that config.h was unchanged, 'touch config.h'"
+ @echo "to suppress this message and continue compiling."
+ @exit 1
+
+options.h: options.h.dist
+ @echo "Please use 'make update' to update your options.h file from options.h.dist"
+ @echo "You must cp options.h.dist to options.h and edit it."
+ @exit 1
+
+autogen: hdrs/cmds.h hdrs/funs.h hdrs/switches.h
+
+hdrs/cmds.h: src/cmds.c src/command.c src/cque.c src/help.c src/set.c src/sql.c Patchlevel
+ @PERL@ utils/mkcmds.pl commands
+
+hdrs/switches.h: src/SWITCHES Patchlevel
+ @PERL@ utils/mkcmds.pl switches
+
+src/switchinc.c: src/SWITCHES Patchlevel
+ @PERL@ utils/mkcmds.pl switches
+
+hdrs/funs.h: src/fun*.c src/bsd.c src/conf.c src/extmail.c src/help.c src/markup.c src/wiz.c src/sql.c Patchlevel
+ @PERL@ utils/mkcmds.pl functions
+
+hdrs/patches.h: patches/*
+ @PERL@ utils/mkcmds.pl patches
+
+install: localized all
+ -rm -f game/netmush
+ -rm -f game/info_slave
+ (cd game; $(INSTALL_LINKS))
+ (cd game/txt; make)
+ @echo "If you plan to run multiple MUSHes, consider running 'make customize'"
+
+netmud:
+ (cd src; make netmud "CC=$(CC)" "CCFLAGS=$(CCFLAGS)" \
+ "SQL_CFLAGS=$(SQL_CFLAGS)" "SQL_LDFLAGS=$(SQL_LDFLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" "CLIBS=$(CLIBS)" )
+
+access:
+ utils/make_access_cnf.sh game
+
+pennmush.pot:
+ (cd src; make ../po/pennmush.pot)
+
+localized:
+ -echo "Localizing for your locale..."
+ -(cd po; make localized)
+
+portmsg:
+ (cd src; make portmsg "CC=$(CC)" "CCFLAGS=$(CCFLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" "CLIBS=$(CLIBS)" )
+
+ssl_slave:
+ (cd src; make ssl_slave "CC=$(CC)" "CCFLAGS=$(CCFLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" "CLIBS=$(CLIBS)" "MAKE=$(MAKE)" \
+ "MAKEFLAGS=$(MAKEFLAGS)")
+
+versions: CHANGES*
+ -@rm -rf CHANGES*~ CHANGES*bak
+ @utils/mkvershlp.pl game/txt/hlp CHANGES*
+
+safety:
+ $(CP) src/*.c
+ $(CP) hdrs/*.h
+ $(CP) *
+
+distdepend: hdrs/funs.h hdrs/cmds.h
+ (cd src; @MAKE@ depend "CC=$(CC)" "CCFLAGS=$(CCFLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" "CLIBS=$(CLIBS)" )
+
+# REQUIRES GNU INDENT! DON'T INDENT WITH ANYTHING ELSE!
+indent:
+ @(cd src; make indent)
+
+customize: update-conf
+ -@@PERL@ utils/customize.pl
+
+# The default place to find the runtime files is in this directory,
+# but it can be overridden with env variables so people can use
+# other game directories.
+GAMEDIR=game
+
+update-conf: game/mush.cnf game/alias.cnf game/restrict.cnf game/names.cnf game/restart
+
+$(GAMEDIR)/alias.cnf: game/aliascnf.dst
+ -@@TOUCH@ game/aliascnf.dst
+ -@@PERL@ utils/update-cnf.pl $(GAMEDIR)/alias.cnf game/aliascnf.dst
+
+$(GAMEDIR)/restrict.cnf: game/restrictcnf.dst
+ -@@TOUCH@ game/restrictcnf.dst
+ -@@PERL@ utils/update-cnf.pl $(GAMEDIR)/restrict.cnf game/restrictcnf.dst
+
+$(GAMEDIR)/names.cnf: game/namescnf.dst
+ if [ ! -f game/names.cnf ]; then \
+ $(CP) game/namescnf.dst $(GAMEDIR)/names.cnf; \
+ fi
+
+$(GAMEDIR)/restart: game/restart.dst
+ifeq ("$(shell which bash)", "")
+ @echo "********************************************************************************";
+ @echo "* Restart script has been updated in this distribution. *";
+ @echo "* However, bash has not been installed on your system. *";
+ @echo "* Please cp game/restart.dst to game/restart if you would like our updated *";
+ @echo "* restart script. *";
+ @echo "********************************************************************************";
+else
+ -@@BASH@ utils/checkrestart.sh
+endif
+
+
+$(GAMEDIR)/mush.cnf: game/mushcnf.dst
+ -@@TOUCH@ game/mushcnf.dst
+ -@@PERL@ utils/update-cnf.pl $(GAMEDIR)/mush.cnf game/mushcnf.dst
+
+update: update-hdr update-conf
+
+update-hdr:
+ -@@TOUCH@ options.h.dist
+ -@sleep 2
+ -@@PERL@ utils/update.pl options.h options.h.dist
+
+test: netmud
+ (cd test; @PERL@ alltests.pl)
+
+clean:
+ (cd src; make clean)
+ (cd game; rm -f netmush info_slave netmush~ info_slave~)
+
+distclean:
+ (cd hdrs; rm -f *.orig *~ \#* *.rej *.bak funs.h cmds.h buildinf.h patches.h)
+ (cd utils; rm -f *.orig *~ \#* *.rej *.bak mkcmds.sh *.o)
+ (cd game; rm -rf *.log netmush info_slave *.orig *.rej *~ *.bak mush.cnf)
+ (cd src; make distclean; rm -f Makefile)
+ (cd game/txt; make clean)
+ (rm -rf .config Makefile config.h config.sh options.h)
+
+totallyclean: distclean
+ (cd hdrs; rm -rf *.rej)
+ (cd src; rm -rf *.rej)
+ -rm -f Makefile
+
+diffs:
+ @make indent > /dev/null 2>&1
+ @make versions > /dev/null 2>&1
+ @make touchswitches > /dev/null 2>&1
+ @make autogen > /dev/null 2>&1
+ @(prcs diff -r$(VS) -N cobramush `cat MANIFEST` | grep -v 'Index:')
+
+commit: indent
+ @svn commit
+
+patch: versions
+ @make-patch-header
+ @make diffs
+
+etags:
+ (cd src; make etags)
+
+ctags:
+ (cd src; make ctags)
+
+touchswitches:
+ @@TOUCH@ src/SWITCHES
+
+globalinstall: install
+ (cd game/txt; make clean compose.sh)
+# $(INSTALLDIR) $(GLOBAL_INSTALL)
+ $(CP) -R game/* $(GLOBAL_INSTALL)
+ rm -f $(GLOBAL_INSTALL)/netmush $(GLOBAL_INSTALL)/info_slave
+ $(INSTALL) config.sh $(GLOBAL_INSTALL)/config.sh
+ $(INSTALL) src/netmud $(GLOBAL_INSTALL)/netmush
+ $(INSTALL) src/info_slave utils/ln-dir.sh $(GLOBAL_INSTALL)
+ $(CHMOD) a+rX -R $(GLOBAL_INSTALL)
+ @echo "** Files installed in $(GLOBAL_INSTALL). Feel free to move them."
+ @echo "** You can run $(GLOBAL_INSTALL)/ln-dir.sh to create a user directory,"
+ @echo "** or symlink that to somewhere easier to run. You may wish to strip them."
+
+
result. It is useful in converting between cartesian and polar
coordinates.
- See HELP CTU() for more on the angle type.
+ See 'HELP CTU()' for more on the angle type.
& ATRLOCK()
- atrlock(<object>/<attrib>[, <on|off>])
+ atrlock(<object>/<attrib>[, <boolexp>])
When given a single object/attribute pair as an argument, returns 1
if the attribute is locked, 0 if unlocked, and #-1 if the attribute
char command_log[256]; /**< File to log suspect commands */
char trace_log[256]; /**< File to log trace data */
char checkpt_log[256]; /**< File to log checkpoint data */
-#ifdef HAS_MYSQL
+ char chatlog_dir[256]; /**< Directory to store chat logs */
char sql_platform[256]; /**< Type of SQL server, or "disabled" */
char sql_host[256]; /**< Hostname of sql server */
char sql_username[256]; /**< Username for sql */
#define CMDLOG (options.command_log)
#define TRACELOG (options.trace_log)
#define CHECKLOG (options.checkpt_log)
-#ifdef HAS_MYSQL
+ #define CHATLOGDIR (options.chatlog_dir)
#define SQL_PLATFORM (options.sql_platform)
#define SQL_HOST (options.sql_host)
#define SQL_DB (options.sql_database)
* into a sorted linked list.
*/
struct channel {
- char name[CHAN_NAME_LEN]; /**< Channel name */
- char title[CHAN_TITLE_LEN]; /**< Channel description */
- long int type; /**< Channel flags */
- long int cost; /**< What it cost to make this channel */
- long int creator; /**< This is who paid the cost for the channel */
- long int cobj; /**< Channel object or #-1 */
- long int num_users; /**< Number of connected users */
- long int max_users; /**< Maximum allocated users */
- struct chanuser *users; /**< Linked list of current users */
- long int num_messages; /**< How many messages handled by this chan since startup */
- boolexp joinlock; /**< Who may join */
- boolexp speaklock; /**< Who may speak */
- boolexp modifylock; /**< Who may change things and boot people */
- boolexp seelock; /**< Who can see this in a list */
- boolexp hidelock; /**< Who may hide from view */
- struct channel *next; /**< Next channel in linked list */
- BUFFERQ *bufferq; /**< Pointer to channel recall buffer queue */
+ char name[CHAN_NAME_LEN]; /**< Channel name */
+ char title[CHAN_TITLE_LEN]; /**< Channel description */
+ privbits type; /**< Channel flags */
+ int cost; /**< What it cost to make this channel */
+ dbref creator; /**< This is who paid the cost for the channel */
+ dbref mogrifier; /**< This is the object that mogrifies the channel text. */
+ int num_users; /**< Number of connected users */
+ int max_users; /**< Maximum allocated users */
+ struct chanuser *users; /**< Linked list of current users */
+ unsigned long int num_messages; /**< How many messages handled by this chan since startup */
+ boolexp joinlock; /**< Who may join */
+ boolexp speaklock; /**< Who may speak */
+ boolexp modifylock; /**< Who may change things and boot people */
+ boolexp seelock; /**< Who can see this in a list */
+ boolexp hidelock; /**< Who may hide from view */
+ struct channel *next; /**< Next channel in linked list */
+ BUFFERQ *bufferq; /**< Pointer to channel recall buffer queue */
+ FILE *logfile; /**< File to log channel in */
};
/** A list of channels on an object.
/* Channel type flags and macros */
-#define CHANNEL_PLAYER 0x1 /* Players may join */
-#define CHANNEL_OBJECT 0x2 /* Objects may join */
-#define CHANNEL_DISABLED 0x4 /* Channel is turned off */
-#define CHANNEL_QUIET 0x8 /* No broadcasts connect/disconnect */
-#define CHANNEL_ADMIN 0x10 /* Admins only */
-#define CHANNEL_DIRECTOR 0x20 /* Directors only */
-#define CHANNEL_CANHIDE 0x40 /* Can non-DARK players hide here? */
-#define CHANNEL_OPEN 0x80 /* Can you speak if you're not joined? */
-#define CHANNEL_NOTITLES 0x100 /* Don't show titles of speakers */
-#define CHANNEL_NONAMES 0x200 /* Don't show names of speakers */
-#define CHANNEL_NOCEMIT 0x400 /* Disallow @cemit */
-#define CHANNEL_COBJ 0x800 /* Channel with a channel object */
-#define CHANNEL_INTERACT 0x1000 /* Filter channel output through interactions */
-#define CHANNEL_LOG 0x2000 /* Log the channel to a file */
+#define CHANNEL_PLAYER 0x1U /* Players may join */
+#define CHANNEL_OBJECT 0x2U /* Objects may join */
+#define CHANNEL_DISABLED 0x4U /* Channel is turned off */
+#define CHANNEL_QUIET 0x8U /* No broadcasts connect/disconnect */
+#define CHANNEL_ADMIN 0x10U /* Wizard and royalty only ok */
+#define CHANNEL_DIRECTOR 0x20U /* Wizard only ok */
+#define CHANNEL_CANHIDE 0x40U /* Can non-DARK Wizards hide here? */
+#define CHANNEL_OPEN 0x80U /* Can you speak if you're not joined? */
+#define CHANNEL_NOTITLES 0x100U /* Don't show titles of speakers */
+#define CHANNEL_NONAMES 0x200U /* Don't show names of speakers */
+#define CHANNEL_NOCEMIT 0x400U /* Disallow @cemit */
+#define CHANNEL_INTERACT 0x800U /* Filter channel output through interactions */
++#define CHANNEL_LOG 0x2000U /* Log the channel to a file */
#define CHANNEL_DEFAULT_FLAGS (CHANNEL_PLAYER)
#define CL_JOIN 0x1
#define CL_SPEAK 0x2
#define Channel_Object(c) (ChanType(c) & CHANNEL_OBJECT)
#define Channel_Player(c) (ChanType(c) & CHANNEL_PLAYER)
#define Channel_Disabled(c) (ChanType(c) & CHANNEL_DISABLED)
-#define Channel_Director(c) (ChanType(c) & CHANNEL_DIRECTOR)
+#define Channel_Wizard(c) (ChanType(c) & CHANNEL_DIRECTOR)
#define Channel_Admin(c) (ChanType(c) & CHANNEL_ADMIN)
++#define Channel_Director(c) (ChanType(c) & CHANNEL_DIRECTOR)
#define Channel_CanHide(c) (ChanType(c) & CHANNEL_CANHIDE)
#define Channel_NoTitles(c) (ChanType(c) & CHANNEL_NOTITLES)
#define Channel_NoNames(c) (ChanType(c) & CHANNEL_NONAMES)
#define Channel_NoCemit(c) (ChanType(c) & CHANNEL_NOCEMIT)
#define Channel_Interact(c) (ChanType(c) & CHANNEL_INTERACT)
+ #define Channel_Log(c) (ChanType(c) & CHANNEL_LOG)
#define Chan_Ok_Type(c,o) \
- ((ChanObj(c) == o) || (IsPlayer(o) && Channel_Player(c)) || \
+ ((IsPlayer(o) && Channel_Player(c)) || \
(IsThing(o) && Channel_Object(c)))
#define Chan_Can(p,t) \
- (!(t & CHANNEL_DISABLED) && (!(t & CHANNEL_DIRECTOR) || Director(p)) || \
- (!(t & CHANNEL_ADMIN) || Admin(p) || div_powover(p,p,"Chat")))
+ (!(t & CHANNEL_DISABLED) && (!(t & CHANNEL_DIRECTOR) || Director(p)) && \
+ (!(t & CHANNEL_ADMIN) || Admin(p) || (div_powover(p,p,"Chat"))))
/* Who can change channel privileges to type t */
-#define Chan_Can_Priv(p,t,c) (!((t & CHANNEL_COBJ) && !(c & CHANNEL_COBJ)) && !(!(t & CHANNEL_COBJ) && (c & CHANNEL_COBJ)) && Chan_Can(p,t))
+#define Chan_Can_Priv(p,t) (Chan_Can(p,t))
#define Chan_Can_Access(c,p) (Chan_Can(p,ChanType(c)))
+#define ChanMogrifier(c) ((c)->mogrifier)
#define Chan_Can_Join(c,p) \
(Chan_Can_Access(c,p) && \
- (eval_chan_lock(c,p,CLOCK_JOIN)))
+ (eval_chan_lock(c,p, CLOCK_JOIN)))
#define Chan_Can_Speak(c,p) \
(Chan_Can_Access(c,p) && \
- (Loud(p) || eval_chan_lock(c,p, CLOCK_SPEAK)))
+ (eval_chan_lock(c,p, CLOCK_SPEAK)))
#define Chan_Can_Cemit(c,p) \
(!Channel_NoCemit(c) && Chan_Can_Speak(c,p))
#define Chan_Can_Modify(c,p) \
#define HugeQueue(x) OOREF(x,div_powover(x,x,"Queue"),div_powover(ooref,ooref,"Queue"))
#define LookQueue(x) OOREF(x,div_powover(x,x,"See_Queue"),div_powover(ooref,ooref,"See_Queue"))
#define CanSeeQ(x,y) OOREF(x,div_powover(x,y,"See_Queue"),div_powover(ooref,y,"See_Queue"))
-
+ #define CanLink(x,y) OOREF(x,div_powover(x,y,"Link"),div_powover(ooref,y,"Link"))
#define HaltAny(x) (Director(x) && OOREF(x,div_powover(x,x,"Halt"),div_powover(ooref,ooref,"Halt")))
#define CanHalt(x,y) OOREF(x,div_powover(x,y,"Halt"),div_powover(ooref,y,"Halt"))
-#define CanNuke(x,y) OOREF(x,div_powover(x,y,"Nuke"),div_powover(ooref, y, "Nuke"))
+#define CanNuke(x,y) OOREF(x,div_powover(x,y,"Nuke"),div_powover(ooref, y, "Nuke"))
#define TC_NoPay(x) (div_powover(x,x,"NoPay") || div_powover(Owner(x),Owner(x),"NoPay"))
-#define NoPay(x) OOREF(x,TC_NoPay(x),TC_NoPay(ooref))
+#define NoPay(x) OOREF(x,TC_NoPay(x),TC_NoPay(ooref))
#define TC_MoneyAdmin(x) (NoPay(x) && Prived(x))
-#define MoneyAdmin(x) OOREF(x,TC_MoneyAdmin(x),TC_MoneyAdmin(ooref))
+#define MoneyAdmin(x) OOREF(x,TC_MoneyAdmin(x),TC_MoneyAdmin(ooref))
#define TC_NoQuota(x) (div_powover(x,x,"NoQuota") || div_powover(Owner(x),Owner(x),"NoQuota"))
-#define TC_DNoQuota(x) (!!has_power(x, "NoQuota"))
-#define NoQuota(x) (IsDivision(x) ? OOREF(x,TC_DNoQuota(x), TC_DNoQuota(ooref)) : OOREF(x,TC_NoQuota(x),TC_NoQuota(ooref)))
+#define TC_DNoQuota(x) (!!has_power(x, "NoQuota"))
+#define NoQuota(x) (IsDivision(x) ? OOREF(x,TC_DNoQuota(x), TC_DNoQuota(ooref)) : OOREF(x,TC_NoQuota(x),TC_NoQuota(ooref)))
#define CanSearch(x,y) OOREF(x,(Owner(x) == Owner(y) || div_powover(x,y,"Search")),(Owner(ooref) == Owner(y) || div_powover(ooref,y,"Search") ))
#define Global_Funcs(x) OOREF(x,div_powover(x,x,"GFuncs"),div_powover(ooref,ooref,"GFuncs"))
#define Create_Player(x) OOREF(x,div_powover(x,x,"PCreate"),div_powover(ooref,ooref,"PCreate"))
--- /dev/null
- lua_myincs="lua5.1 lua-5.1.4"
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_lua.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_WITH_LUA
+# AX_PROG_LUA [(MIN-VERSION, [TOO-BIG-VERSION])]
+# AX_LUA_VERSION (MIN-VERSION, [TOO-BIG-VERSION])
+# AX_LUA_HEADERS
+# AX_LUA_HEADERS_VERSION (MIN-VERSION, [TOO-BIG-VERSION])
+# AX_LUA_LIBS
+# AX_LUA_READLINE
+#
+# DESCRIPTION
+#
+# Detect Lua interpreter, headers and libraries, optionally enforcing a
+# particular range of versions. If only one version is given, then exactly
+# this version is required.
+#
+# AX_WITH_LUA searches for a Lua interpreter and defines LUA if found.
+#
+# AX_PROG_LUA searches for a Lua interpreter in the given version range,
+# if any, and defines LUA if found, or stops with an error if not.
+#
+# AX_LUA_VERSION checks that the version of Lua is at least MIN-VERSION
+# and less than TOO-BIG-VERSION, if given.
+#
+# AX_LUA_HEADERS searches for Lua headers and defines HAVE_LUA_H and
+# HAVE_LUALIB_H if found, and defines LUA_INCLUDE to the preprocessor
+# flags needed, if any.
+#
+# AX_LUA_HEADERS_VERSION checks that the Lua headers' version is at least
+# MIN-VERSION, and less than TOO-BIG-VERSION, if given.
+#
+# AX_LUA_LIBS searches for Lua libraries and defines LUA_LIB if found.
+#
+# AX_LUA_READLINE configures Lua to be built with readline support, if
+# available. This macro requires AX_LIB_READLINE.
+#
+# Versions are specified as three-digit integers whose first digit is the
+# major version and last two are the minor version (the same format as
+# LUA_VERSION_NUM in lua.h); e.g. 501 for Lua 5.1. The revision (e.g. the
+# "3" in "5.1.3") is ignored.
+#
+# The following options are added by these macros:
+#
+# --with-lua-suffix=ARG Lua binaries and library files are
+# suffixed with ARG.
+#
+# LICENSE
+#
+# Copyright (c) 2011 Reuben Thomas <rrt@sc3d.org>
+# Copyright (c) 2009 Matthieu Moy <Matthieu.Moy@imag.fr>
+# Copyright (c) 2009 Tom Payne <twpayne@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 14
+
+dnl Helper function from previous metaconf methods
+dnl
+ AC_DEFUN([AX_CHECK_LOCAL_LUA],
+ [
+ AC_MSG_NOTICE([Checking lua in local directories...])
- AC_SEARCH_LIBS([lua_call], [lua lua5.1], , AC_MSG_ERROR([CobraMUSH requires lua]))], [
++ lua_myincs="lua5.1 lua-5.1.4 lua5.2"
+ lua_otherincs=""
+ lua_thisincl=""
+ for lua_thisincl in $lua_myincs; do
+ thispath=`pwd`
+ AC_MSG_CHECKING([Checking in $thispath/$lua_thisincl])
+ if test -f "$thispath/$lua_thisincl/src/lua.h"; then
+ lua_h_path="$thispath/$lua_thisincl/src"
+ AC_MSG_RESULT([yes.. found in sub src direcctory])
+ break
+ elif test -r "$thispath/$lua_thisincl/lua.h"; then
+ lua_h_path="$thispath/$lua_thisincl"
+ AC_MSG_RESULT([yes])
+ break
+ else
+ lua_otherincs="$lua_otherincs $thisincl $thisincl/src"
+ AC_MSG_RESULT([no])
+ fi
+ done
+
+ AC_MSG_CHECKING([Checking for local lua lib at $lua_h_path])
+ if test -f "$lua_h_path/liblua.a"; then
+ AC_MSG_RESULT([found])
+ lua_ldflags="-L$lua_h_path"
+ else
+ AC_MSG_NOTICE([Could not locate local LUA library.])
+ AC_MSG_ERROR([Either install LUA development global libraries or compile your local LUA installation])
+ fi
+ ])
+
+AC_DEFUN([AX_FIND_LUA],[
+ AC_CHECK_HEADER([lua.h], [
- AC_SEARCH_LIBS([lua_call], [lua lua5.1], , AC_MSG_ERROR([CobraMUSH requires lua]))
++ AC_SEARCH_LIBS([lua_callk], [lua lua5.1 lua5.2], , AC_MSG_ERROR([CobraMUSH requires lua]))], [
+ AX_CHECK_LOCAL_LUA()
+ LDFLAGS="$LDFLAGS $lua_ldflags"
+ CFLAGS="$CFLAGS -I$lua_h_path"
++ AC_SEARCH_LIBS([lua_callk], [lua lua5.1 lua5.2], , AC_MSG_ERROR([CobraMUSH requires lua]))
+ ])])
+
+dnl Helper function to declare extra options
+AC_DEFUN([_AX_LUA_OPTS],
+ [AC_ARG_WITH([lua-suffix],
+ [AS_HELP_STRING([--with-lua-suffix=ARG],
+ [Lua binary and library files are suffixed with ARG])])])dnl
+
+AC_DEFUN([AX_WITH_LUA],
+ [_AX_LUA_OPTS
+ if test "x$LUA" = x; then
+ AC_PATH_PROG(LUA, lua$with_lua_suffix)
+ fi])dnl
+
+AC_DEFUN([AX_PROG_LUA],
+ [lua_min_version=$1
+ lua_max_version=$2
+ AX_WITH_LUA
+ if test -z "$LUA"; then
+ AC_MSG_FAILURE([Lua not found])
+ fi
+ if test -n "$lua_min_version"; then
+ AX_LUA_VERSION($lua_min_version, $lua_max_version)
+ fi
+ AC_SUBST(LUA)])dnl
+
+dnl Helper function to parse minimum & maximum versions
+AC_DEFUN([_AX_LUA_VERSIONS],
+ [lua_min_version=$1
+ lua_max_version=$2
+ if test "x$lua_min_version" = x; then
+ lua_min_version=0
+ fi
+ if test "x$lua_max_version" = x; then
+ lua_max_version=$(($lua_min_version + 1))
+ fi])
+
+AC_DEFUN([AX_LUA_VERSION],
+ [_AX_LUA_OPTS
+ _AX_LUA_VERSIONS($1, $2)
+ AC_MSG_CHECKING([Lua version is in range $1 <= v < $2])
+ if test "x$LUA" != x; then
+ lua_text_version=$(LUA_INIT= $LUA -e 'print(_VERSION)' 2>&1 | cut -d' ' -f2)
+ case $lua_text_version in
+ 5.2*)
+ lua_version=502
+ ;;
+ 5.1*)
+ lua_version=501
+ ;;
+ 5.0*)
+ lua_version=500
+ ;;
+ 4.0*)
+ lua_version=400
+ ;;
+ *)
+ lua_version=-1
+ ;;
+ esac
+ if test $lua_version -ge "$lua_min_version" && test $lua_version -lt "$lua_max_version"; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_FAILURE([Lua version not in desired range.])
+ fi
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_FAILURE([Lua version not in desired range.])
+ fi])dnl
+
+AC_DEFUN([AX_LUA_HEADERS],
+ [_AX_LUA_OPTS
+ LUA_OLD_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $LUA_INCLUDE"
+ AC_CHECK_HEADERS([lua.h lualib.h])
+ CPPFLAGS="$LUA_OLD_CPPFLAGS"]
+ )dnl
+
+dnl Finder header location and place it in LUA_HEADER_PATH
+
+AC_DEFUN([AX_LUA_LIBS],
+ [_AX_LUA_OPTS
+ AC_CHECK_LIB([m], [exp], [lua_extra_libs="$lua_extra_libs -lm"], [])
+ AC_CHECK_LIB([dl], [dlopen], [lua_extra_libs="$lua_extra_libs -ldl"], [])
+ AC_CHECK_LIB([lua$with_lua_suffix],
+ [lua_call],
+ [LUA_LIB="$LUA_LIB -llua$with_lua_suffix $lua_extra_libs"],
+ [],
+ [$LUA_LIB $lua_extra_libs])])dnl
+
+AC_DEFUN([AX_LUA_HEADERS_VERSION],
+ [_AX_LUA_OPTS
+ _AX_LUA_VERSIONS($1, $2)
+ AC_MSG_CHECKING([lua.h version is in range $1 <= v < $2])
+ LUA_OLD_LIBS="$LIBS"
+ LIBS="$LIBS $LUA_LIB"
+ LUA_OLD_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $LUA_INCLUDE"
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <lua.h>
+#include <stdlib.h>
+#include <stdio.h>
+int main()
+{
+ printf("(found %s, %d)... ", LUA_VERSION, LUA_VERSION_NUM);
+ if (LUA_VERSION_NUM >= $lua_min_version && LUA_VERSION_NUM < $lua_max_version)
+ exit(EXIT_SUCCESS);
+ exit(EXIT_FAILURE);
+}
+]])],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ AC_MSG_FAILURE([lua.h version not in desired range])])
+ LIBS="$LUA_OLD_LIBS"
+ CPPFLAGS="$LUA_OLD_CPPFLAGS"])dnl
+
+AC_DEFUN([AX_LUA_READLINE],
+ [AX_LIB_READLINE
+ if test -n "$ac_cv_header_readline_readline_h" && test -n "$ac_cv_header_readline_history_h"; then
+ LUA_LIBS_CFLAGS="-DLUA_USE_READLINE $LUA_LIBS_CFLAGS"
+ fi])dnl
close_sockets(void)
{
DESC *d, *dnext;
- ssize_t res;
+ const char *shutmsg;
+ int shutlen;
+
+ shutmsg = T(shutdown_message);
+ shutlen = strlen(shutmsg);
for (d = descriptor_list; d; d = dnext) {
dnext = d->next;
-#ifdef COMPILE_CONSOLE
- if(d->descriptor == 0) {
- write(STDOUT_FILENO, T(shutdown_message), strlen(T(shutdown_message)));
- write(STDOUT_FILENO, "\r\n", 2);
+#ifdef HAVE_SSL
+ if (!d->ssl) {
+#endif
+#ifdef HAVE_WRITEV
+ struct iovec byebye[2];
+ byebye[0].iov_base = (char *) shutmsg;
+ byebye[0].iov_len = shutlen;
+ byebye[1].iov_base = (char *) "\r\n";
+ byebye[1].iov_len = 2;
- /* FIXME: We're using res.. for the mere fact we get a warning otherwise.. */
- res = writev(d->outdesc, byebye, 2);
++ (void) writev(d->outdesc, byebye, 2);
+#else
+ if (d->outdesc == console_outpt) {
+ write(d->outdesc, shutmsg, shutlen);
+ write(d->outdesc, (char *) "\r\n", 2);
+ } else {
+ send(d->outdesc, shutmsg, shutlen, 0);
+ send(d->outdesc, (char *) "\r\n", 2, 0);
+ }
+#endif
+#ifdef HAVE_SSL
} else {
- send(d->descriptor, T(shutdown_message), strlen(T(shutdown_message)), 0);
- send(d->descriptor, "\r\n", 2, 0);
- if (shutdown(d->descriptor, 2) < 0)
- perror("shutdown");
- closesocket(d->descriptor);
- }
-#else /* COMPILE_CONSOLE */
- send(d->descriptor, T(shutdown_message), strlen(T(shutdown_message)), 0);
- send(d->descriptor, "\r\n", 2, 0);
-#ifdef HAS_OPENSSL
- if (d->ssl) {
+ int offset;
+ offset = 0;
+ ssl_write(d->ssl, d->ssl_state, 0, 1, (uint8_t *) shutmsg,
+ shutlen, &offset);
+ offset = 0;
+ ssl_write(d->ssl, d->ssl_state, 0, 1, (uint8_t *) "\r\n", 2,
+ &offset);
+ const char *shutmsg = T(shutdown_message);
+ offset = 0;
+ ssl_write(d->ssl, d->ssl_state, 0, 1, (uint8_t *) shutmsg,
+ strlen(shutmsg), &offset);
+ offset = 0;
+ ssl_write(d->ssl, d->ssl_state, 0, 1, (uint8_t *) "\r\n", 2,
+ &offset);
ssl_close_connection(d->ssl);
d->ssl = NULL;
d->ssl_state = 0;
#include <sys/types.h>
#endif
#include <stdarg.h>
+ #include <sys/stat.h>
+ #include <errno.h>
#include "conf.h"
+
+#ifdef CHAT_SYSTEM
#include "externs.h"
#include "attrib.h"
#include "mushdb.h"
static void do_channel_who(dbref player, CHAN *chan);
void chat_player_announce(dbref player, char *msg, int ungag);
static int ok_channel_name(const char *n);
-static void format_channel_broadcast(CHAN *chan, CHANUSER *u, dbref victim,
- int flags, const char *msg,
- const char *extra);
+/*
+static void format_channel_chat(CHAN *chan, CHANUSER *u, dbref victim,
+ int flags, const char *msg, const char *extra);
+ */
+static void channel_send(CHAN *channel, dbref player, int flags,
+ const char *origmessage);
static void list_partial_matches(dbref player, const char *name,
- enum chan_match_type type);
+ enum chan_match_type type);
+ static void begin_chat_log(CHAN *chan);
+ static void end_chat_log(CHAN *chan);
+ static void write_chat_log(CHAN *chan, char *buf);
-const char *chan_speak_lock = "ChanSpeakLock"; /**< Name of speak lock */
-const char *chan_join_lock = "ChanJoinLock"; /**< Name of join lock */
-const char *chan_mod_lock = "ChanModLock"; /**< Name of modify lock */
-const char *chan_see_lock = "ChanSeeLock"; /**< Name of see lock */
-const char *chan_hide_lock = "ChanHideLock"; /**< Name of hide lock */
+const char *chan_speak_lock = "ChanSpeakLock"; /**< Name of speak lock */
+const char *chan_join_lock = "ChanJoinLock"; /**< Name of join lock */
+const char *chan_mod_lock = "ChanModLock"; /**< Name of modify lock */
+const char *chan_see_lock = "ChanSeeLock"; /**< Name of see lock */
+const char *chan_hide_lock = "ChanHideLock"; /**< Name of hide lock */
-#define CYES 1 /**< An affirmative. */
-#define CNO 0 /**< A negative. */
-#define ERR -1 /**< An error. Clever, eh? */
+slab *channel_slab; /**< slab for 'struct channel' allocations */
+slab *chanlist_slab; /**< slab for 'struct chanlist' allocations */
+slab *chanuser_slab; /**< slab for 'struct chanuser' allocations */
+
+#define CHAN_YES 1 /**< An affirmative. */
+#define CHAN_NO 0 /**< A negative. */
+#define CHAN_ERR -1 /**< An error. Clever, eh? */
/** Wrapper for insert_user() that generates a new CHANUSER and inserts it */
#define insert_user_by_dbref(who,chan) \
{"NoNames", 'N', CHANNEL_NONAMES, CHANNEL_NONAMES},
{"NoCemit", 'C', CHANNEL_NOCEMIT, CHANNEL_NOCEMIT},
{"Interact", 'I', CHANNEL_INTERACT, CHANNEL_INTERACT},
- {"ChanObj", 'Z', CHANNEL_COBJ, CHANNEL_COBJ},
+ {"LogChannel", 'L', CHANNEL_LOG, CHANNEL_LOG},
{NULL, '\0', 0, 0}
};
channel_join_self(dbref player, const char *name)
{
CHAN *chan = NULL;
-- CHANUSER *u;
if (Guest(player)) {
notify(player, T("Guests are not allowed to join channels."));
}
}
if (insert_user_by_dbref(player, chan)) {
- notify_format(player, T("CHAT: You join channel %s."), ChanObjName(chan));
- u = onchannel(player, chan);
- if (!Channel_Quiet(chan) && !DarkLegal(player))
- format_channel_broadcast(chan, u, player, CB_CHECKQUIET | CB_PRESENCE,
- T("%s %s has joined this channel."), NULL);
+ notify_format(player, T("CHAT: You join channel <%s>."), ChanName(chan));
- u = onchannel(player, chan);
ChanNumUsers(chan)++;
+ if (!Channel_Quiet(chan) && !DarkLegal(player))
+ channel_send(chan, player,
+ CB_CHECKQUIET | CB_PRESENCE | CB_POSE,
+ T("has joined this channel."));
} else {
/* Should never happen */
notify_format(player,
do_chat(dbref player, CHAN *chan, const char *arg1)
{
CHANUSER *u;
-- const char *gap;
- const char *someone = "Someone";
- char *title;
- const char *name;
- int canhear;
+ char type;
+ bool canhear;
if (!Chan_Ok_Type(chan, player)) {
notify_format(player,
return;
}
- if (!Channel_NoTitles(chan) && u &&CUtitle(u) && *CUtitle(u))
- title = CUtitle(u);
- else
- title = NULL;
- if (Channel_NoNames(chan))
- name = NULL;
- else
- name = accented_name(player);
- if (!title && !name)
- name = someone;
-
/* figure out what kind of message we have */
-- gap = " ";
+ type = ':';
switch (*arg1) {
case SEMI_POSE_TOKEN:
-- gap = "";
+ type = ';';
/* FALLTHRU */
case POSE_TOKEN:
arg1 = arg1 + 1;
if (type)
ChanType(chan) = type;
ChanCreator(chan) = Owner(player);
- strcpy(ChanName(chan), name);
+ ChanMogrifier(chan) = NOTHING;
+ mush_strncpy(ChanName(chan), name, CHAN_NAME_LEN);
insert_channel(&chan);
+ if(Channel_Log(chan))
+ begin_chat_log(chan);
notify_format(player, T("CHAT: Channel <%s> created."), ChanName(chan));
break;
case 1:
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));
+ if(Channel_Log(chan))
+ begin_chat_log(chan);
+ snprintf(announcebuff, BUFFER_LEN, "has renamed %s to %s",
+ old, ChanName(chan));
+ channel_send(chan, player,
+ CB_CHECKQUIET | CB_PRESENCE | CB_POSE, announcebuff);
notify(player, T("Channel renamed."));
break;
case 3:
notify(player, T("Warning: channel will be disabled."));
if (type == ChanType(chan)) {
notify_format(player,
- T
- ("Invalid or same permissions on channel <%s>. No changes made."),
- ChanName(chan));
+ T
+ ("Invalid or same permissions on channel <%s>. No changes made."),
+ ChanName(chan));
} else {
+ if(Channel_Log(chan) && !(type & CHANNEL_LOG))
+ end_chat_log(chan);
+ else if(!Channel_Log(chan) && (type & CHANNEL_LOG))
+ begin_chat_log(chan);
ChanType(chan) = type;
notify_format(player,
- T("Permissions on channel <%s> changed."), ChanName(chan));
+ T("Permissions on channel <%s> changed."), ChanName(chan));
}
break;
}
int numblanks;
if (SUPPORT_PUEBLO)
- notify_noenter(player, tprintf("%cSAMP%c", TAG_START, TAG_END));
- notify_format(player, "%-30s %-5s %8s %-18s %-8s %-3s",
- "Name", "Users", "Msgs", T("Chan Type"), "Status", "Buf");
+ notify_noenter(player, open_tag("SAMP"));
- notify_format(player, "%-30s %-5s %8s %-16s %-8s %-3s",
++ notify_format(player, "%-30s %-5s %8s %-15s %-8s %-3s",
+ T("Name"), T("Users"), T("Msgs"), T("Chan Type"), T("Status"),
+ T("Buf"));
for (c = channels; c; c = c->next) {
strcpy(cleanname, remove_markup(ChanName(c), NULL));
if (Chan_Can_See(c, player) && string_prefix(cleanname, partname)) {
len = strlen(ChanName(c));
numblanks = len - strlen(cleanname);
if (numblanks > 0 && numblanks < CHAN_NAME_LEN) {
- memset(blanks, ' ', CHAN_NAME_LEN - 1);
- if (len > 30)
- numblanks -= (len - 30);
- if (numblanks < 0)
- numblanks = 0;
- blanks[numblanks] = '\0';
+ memset(blanks, ' ', CHAN_NAME_LEN - 1);
+ if (len > 30)
+ numblanks -= (len - 30);
+ if (numblanks < 0)
+ numblanks = 0;
+ blanks[numblanks] = '\0';
} else {
- blanks[0] = '\0';
+ blanks[0] = '\0';
}
notify_format(player,
- "%-30s%s %s %8ld [%c%c%c%c%c%c%c %c%c%c%c%c%c] [%-3s %c%c] %3d",
- ChanName(c), blanks, numusers, ChanNumMsgs(c),
- Channel_Disabled(c) ? 'D' : '-',
- Channel_Player(c) ? 'P' : '-',
- Channel_Object(c) ? 'O' : '-',
- Channel_Admin(c) ? 'A' : (Channel_Wizard(c) ? 'W' : '-'),
- Channel_Quiet(c) ? 'Q' : '-',
- Channel_CanHide(c) ? 'H' : '-', Channel_Open(c) ? 'o' : '-',
- /* Locks */
- ChanJoinLock(c) != TRUE_BOOLEXP ? 'j' : '-',
- ChanSpeakLock(c) != TRUE_BOOLEXP ? 's' : '-',
- ChanModLock(c) != TRUE_BOOLEXP ? 'm' : '-',
- ChanSeeLock(c) != TRUE_BOOLEXP ? 'v' : '-',
- ChanHideLock(c) != TRUE_BOOLEXP ? 'h' : '-',
- /* Does the player own it? */
- ChanCreator(c) == player ? '*' : '-',
- /* User status */
- u ? (Chanuser_Gag(u) ? T("Gag") : T("On")) : T("Off"),
- (u && Chanuser_Quiet(u)) ? 'Q' : ' ',
- (u && Chanuser_Hide(u)) ? 'H' : ' ',
- bufferq_blocks(ChanBufferQ(c)));
- "%-30s%s %s %8ld [%c%c%c%c%c%c%c%c%c %c%c%c%c%c%c] [%-3s %c%c] %3d",
++ "%-30s%s %s %8ld [%c%c%c%c%c%c%c%c %c%c%c%c%c%c] [%-3s %c%c] %3d",
+ ChanName(c), blanks, numusers, ChanNumMsgs(c),
+ Channel_Disabled(c) ? 'D' : '-',
+ Channel_Player(c) ? 'P' : '-',
+ Channel_Object(c) ? 'O' : '-',
+ Channel_Admin(c) ? 'A' : (Channel_Director(c) ? 'W' : '-'),
+ Channel_Quiet(c) ? 'Q' : '-',
+ Channel_CanHide(c) ? 'H' : '-', Channel_Open(c) ? 'o' : '-',
- (ChanType(c) & CHANNEL_COBJ) ? 'Z' : '-',
+ Channel_Log(c) ? 'L' : '-',
+ /* Locks */
+ ChanJoinLock(c) != TRUE_BOOLEXP ? 'j' : '-',
+ ChanSpeakLock(c) != TRUE_BOOLEXP ? 's' : '-',
+ ChanModLock(c) != TRUE_BOOLEXP ? 'm' : '-',
+ ChanSeeLock(c) != TRUE_BOOLEXP ? 'v' : '-',
+ ChanHideLock(c) != TRUE_BOOLEXP ? 'h' : '-',
+ /* Does the player own it? */
+ ChanCreator(c) == player ? '*' : '-',
+ /* User status */
+ u ? (Chanuser_Gag(u) ? "Gag" : "On") : "Off",
+ (u &&Chanuser_Quiet(u)) ? 'Q' : ' ',
+ (u &&Chanuser_Hide(u)) ? 'H' : ' ',
+ bufferq_lines(ChanBufferQ(c)));
}
}
if (SUPPORT_PUEBLO)
if (Channel_Disabled(channel))
return;
- va_start(args, fmt);
+ speaker = onchannel(player, channel);
-#ifdef HAS_VSNPRINTF
- (void) vsnprintf(tbuf1, sizeof tbuf1, fmt, args);
-#else
- (void) vsprintf(tbuf1, fmt, args);
-#endif
- va_end(args);
- tbuf1[BUFFER_LEN - 1] = '\0';
+ snprintf(channame, BUFFER_LEN, "<%s>", ChanName(channel));
+
+ if (!Channel_NoTitles(channel) && speaker &&
+ CUtitle(speaker) && *CUtitle(speaker)) {
+ snprintf(title, BUFFER_LEN, "%s", CUtitle(speaker));
+ } else {
+ title[0] = '\0';
+ }
+
+ if (Channel_NoNames(channel)) {
+ playername[0] = '\0';
+ } else {
+ snprintf(playername, BUFFER_LEN, "%s", accented_name(player));
+ }
+ if (!title[0] && !playername[0]) {
+ snprintf(playername, BUFFER_LEN, "%s", someone);
+ }
+
+ if (flags & CB_PRESENCE) {
+ ctype = "@";
+ } else if (flags & CB_POSE) {
+ ctype = ":";
+ } else if (flags & CB_SEMIPOSE) {
+ ctype = ";";
+ } else if (flags & CB_EMIT) {
+ ctype = "|";
+ } else {
+ ctype = "\"";
+ }
+
+ snprintf(speechtext, BUFFER_LEN, "says");
+
+ snprintf(message, BUFFER_LEN, "%s", origmessage);
+
+ if (GoodObject(ChanMogrifier(channel))) {
+ if (eval_lock(player, ChanMogrifier(channel), Use_Lock)) {
+ mogrifier = ChanMogrifier(channel);
- nac.u = ChanUsers(channel);
- nac.checkquiet = (flags & CB_CHECKQUIET) ? 1 : 0;
- if (Channel_Interact(channel))
+ argv[0] = ctype;
+ argv[1] = ChanName(channel);
+ argv[2] = message;
+ argv[3] = playername;
+ argv[4] = title;
+
+ blockstr = mogrify(mogrifier, "MOGRIFY`BLOCK", player, 6, argv, "");
+ if (blockstr && *blockstr) {
+ notify(player, blockstr);
+ return;
+ }
+ // Do we override chatformats?
+ if (parse_boolean
+ (mogrify(mogrifier, "MOGRIFY`OVERRIDE", player, 6, argv, ""))) {
+ override_chatformat = 1;
+ }
+
+ argv[1] = ChanName(channel);
+ argv[2] = ctype;
+ argv[3] = message;
+ argv[4] = title;
+ argv[5] = playername;
+
+ argv[0] = channame;
+ snprintf(channame, BUFFER_LEN, "%s",
+ mogrify(mogrifier, "MOGRIFY`CHANNAME", player, 6, argv,
+ channame));
+
+ argv[0] = title;
+ snprintf(title, BUFFER_LEN, "%s",
+ mogrify(mogrifier, "MOGRIFY`TITLE", player, 6, argv, title));
+
+ argv[0] = playername;
+ snprintf(playername, BUFFER_LEN, "%s",
+ mogrify(mogrifier, "MOGRIFY`PLAYERNAME", player, 6, argv,
+ playername));
+
+ if (flags & CB_SPEECH) {
+ argv[0] = speechtext;
+ snprintf(speechtext, BUFFER_LEN, "%s",
+ mogrify(mogrifier, "MOGRIFY`SPEECHTEXT", player, 6, argv,
+ speechtext));
+ }
+
+ argv[0] = message;
+ snprintf(message, BUFFER_LEN, "%s",
+ mogrify(mogrifier, "MOGRIFY`MESSAGE", player, 6, argv, message));
+ }
+ }
+
+ bp = buff;
+
+ *bp = '\0';
+
+ if (!(flags & CB_QUIET)) {
+ safe_str(channame, buff, &bp);
+ safe_chr(' ', buff, &bp);
+ }
+
+ if (flags & CB_EMIT) {
+ safe_str(message, buff, &bp);
+ } else {
+ if (!(flags & CB_PRESENCE)) {
+ if (title[0]) {
+ safe_str(title, buff, &bp);
+ safe_chr(' ', buff, &bp);
+ }
+ }
+ safe_str(playername, buff, &bp);
+ switch (flags & CB_TYPE) {
+ case CB_POSE:
+ safe_chr(' ', buff, &bp);
+ case CB_SEMIPOSE:
+ safe_str(message, buff, &bp);
+ break;
+ case CB_SPEECH:
+ safe_format(buff, &bp, " %s, \"%s\"", T(speechtext), message);
+ break;
+ }
+ }
+ *bp = '\0';
+
+ // @chatformat
+ if (flags & CB_PRESENCE) {
+ snprintf(title, BUFFER_LEN, "%s", message);
+ snprintf(message, BUFFER_LEN, "%s %s", Name(player), title);
+ title[0] = '\0';
+ }
+
+ if (GoodObject(mogrifier)) {
+ argv[0] = ctype;
+ argv[1] = ChanName(channel);
+ argv[2] = message;
+ argv[3] = playername;
+ argv[4] = title;
+ argv[5] = buff;
+ snprintf(buff, BUFFER_LEN, "%s",
+ mogrify(mogrifier, "MOGRIFY`FORMAT", player, 6, argv, buff));
+ }
+
+ if (Channel_Interact(channel)) {
na_flags |= (flags & CB_PRESENCE) ? NA_INTER_PRESENCE : NA_INTER_HEAR;
- notify_anything(player, na_channel, &nac, ns_esnotify,
- na_flags | ((flags & CB_NOSPOOF) ? 0 : NA_SPOOF), tbuf1);
+ }
+
+ if (!(flags & CB_NOSPOOF)) {
+ na_flags |= NA_SPOOF;
+ }
+
+ for (u = ChanUsers(channel); u; u = u->next) {
+ current = CUdbref(u);
+
+ if (!(((flags & CB_CHECKQUIET) && Chanuser_Quiet(u)) ||
+ Chanuser_Gag(u) || (IsPlayer(current) && !Connected(current)))) {
+ if (override_chatformat
+ || !vmessageformat(current, "CHATFORMAT", player,
+ na_flags,
+ 6,
+ ctype,
+ ChanName(channel),
+ message, playername, title, buff)) {
+ notify_anything(player, na_one, ¤t, ns_esnotify, na_flags, buff);
+ }
+ }
+ }
+
if (ChanBufferQ(channel))
add_to_bufferq(ChanBufferQ(channel), 0,
- (flags & CB_NOSPOOF) ? player : NOTHING, tbuf1);
+ (flags & CB_NOSPOOF) ? player : NOTHING, buff);
+ if(Channel_Log(channel))
- write_chat_log(channel, tbuf1);
-}
++ write_chat_log(channel, buff);
+ if (!(flags & CB_PRESENCE) && !speaker) {
+ notify_format(player, T("To channel %s: %s"), ChanName(channel), buff);
+ }
+}
/** Recall past lines from the channel's buffer.
* We try to recall no more lines that are requested by the player,
}
}
- /** Evaluate a channel lock with %0 set to the channel name.
-static void
-format_channel_broadcast(CHAN *chan, CHANUSER *u, dbref victim, int flags,
- const char *msg, const char *extra)
-{
- const char *title = NULL;
- if (extra && *extra)
- title = extra;
- else if (u &&CUtitle(u))
- title = CUtitle(u);
-
- if (Channel_NoNames(chan)) {
- if (Channel_NoTitles(chan) || !title)
- channel_broadcast(chan, victim, flags, msg, ChanObjName(chan), "Someone");
- else
- channel_broadcast(chan, victim, flags, msg, ChanObjName(chan), title);
- } else
- channel_broadcast(chan, victim, flags, msg, ChanObjName(chan), Name(victim));
-}
-
+ static void
+ begin_chat_log(CHAN *chan)
+ {
+ struct stat st;
+ char filename[512];
+ int i, j;
+
+ if(!*CHATLOGDIR)
+ return;
+
+ if(stat(CHATLOGDIR, &st)) {
+ do_rawlog(LT_ERR, T("Unable to stat() chatlog_dir: %s"), strerror(errno));
+ return;
+ }
+
+ if(!S_ISDIR(st.st_mode)) {
+ do_rawlog(LT_ERR, T("chatlog_dir is not a directory"));
+ return;
+ }
+
+ strcpy(filename, CHATLOGDIR); /* N.B.: CHATLOGDIR is at most 256 bytes */
+ i = strlen(filename);
+ if(filename[i-1] != '/') {
+ filename[i] = '/';
+ i++;
+ }
+
+ j = strlen(ChanName(chan));
+ if((i + j) > 507) {
+ do_rawlog(LT_ERR,
+ T("Buffer length exceeded for chat log filename for channel %s"),
+ ChanName(chan));
+ return;
+ }
+
+ strcpy(filename + i, ChanName(chan));
+ i += j;
+
+ strcpy(filename + i, ".log");
+ filename[511] = '\0';
+
+ ChanLogFile(chan) = fopen(filename, "a");
+ if(!ChanLogFile(chan)) {
+ do_rawlog(LT_ERR, T("Unable to open log file for channel %s: %s"),
+ ChanName(chan), strerror(errno));
+ return;
+ }
+
+ write_chat_log(chan, "Beginning of log.");
+ }
+
+ static void
+ end_chat_log(CHAN *chan)
+ {
+ if(!ChanLogFile(chan))
+ return;
+
+ write_chat_log(chan, "End of log.");
+ fclose(ChanLogFile(chan));
+ ChanLogFile(chan) = NULL;
+ }
+
+ static void
+ write_chat_log(CHAN *chan, char *buf)
+ {
+ char tbuf[BUFFER_LEN];
+ struct tm *when;
+ char *clean;
+
+ if(!ChanLogFile(chan))
+ return;
+
+ when = localtime(&mudtime);
+ strftime(tbuf, sizeof tbuf, "[%m/%d %H:%M:%S] ", when);
+ fputs(tbuf, ChanLogFile(chan));
+
+ clean = remove_markup(buf, NULL);
+ fputs(clean, ChanLogFile(chan));
+ fputc('\n', ChanLogFile(chan));
+ fflush(ChanLogFile(chan));
+ }
+
-static void
-do_reset_cobj(player, name)
- dbref player;
- const char *name;
-{
- CHAN *c;
- /* Test Channel */
- test_channel(player, name, c);
- if(!Chan_Can_Modify(c, player)) {
- notify(player, "CHAT: Oh come on.");
- return;
- }
- /* Now lets reset teh chan obj stuff on the channel */
- ChanType(c) &= ~CHANNEL_COBJ;
- ChanObj(c) = -1;
- notify(player,"ChanObj Reset.");
-}
-
-
-static void
-do_set_cobj(player, name, obj)
- dbref player;
- const char *name;
- const char *obj;
-{
- CHAN *c;
- dbref cobj;
- /* Test the channel */
- test_channel(player, name, c);
-
- if(!Chan_Can_Modify(c, player)) {
- notify(player, "CHAT: Oh come on.");
- return;
- }
-
- /* Not sure if all this shit works right, so be careful */
-
- cobj = match_result(player, obj, TYPE_THING, MAT_ABSOLUTE);
-
- if(cobj == -1) {
- notify(player, "Invalid Object");
- return;
- }
-
-
- if(cobj == -2) {
- notify(player, "Ambigious Object");
- return;
- }
-
- if(!controls(player,cobj)) {
- notify(player,"You must own that object first");
- return;
- }
-
- if(Typeof(cobj) != TYPE_THING) {
- notify(player, "Must be an object");
- return;
- }
-
- ChanType(c) |= CHANNEL_COBJ;
- ChanObj(c) = cobj;
-
- notify(player,tprintf("Channel object for %s is now #%ld", ChanName(c),
- ChanObj(c)) );
-
-}
-
-int ChanObjCheck(CHAN *c)
- {
- if(ChanType(c) & CHANNEL_COBJ) {
- if(Typeof(ChanObj(c)) == TYPE_GARBAGE) {
- ChanType(c) &= ~CHANNEL_COBJ;
- ChanObj(c) = -1;
- return 0;
- } else return 1;
- } else return 0;
-}
-
-const char *
-ChanObjName(CHAN *c)
- {
- ATTR *nm;
- static char buff[BUFFER_LEN];
- static char tbuf[BUFFER_LEN];
-
- if(!c)
- return NULL;
-
- if(ChanType(c) & CHANNEL_COBJ) {
- if(Typeof(ChanObj(c)) == TYPE_GARBAGE) {
- ChanType(c) &= ~(CHANNEL_COBJ);
- ChanObj(c) = -1;
- strcpy(buff,tprintf("<%s>", ChanName(c)));
- return buff;
- }
-
- nm = atr_get_noparent(ChanObj(c), "CHANNAME");
- if(nm) {
- strcpy(tbuf,atr_value(nm));
- strcpy(buff,(char *) nv_eval(ChanObj(c), tbuf));
- }
- else {
- strcpy(buff,tprintf("<%s>", ChanName(c)));
- }
- }
- else {
- strcpy(buff,tprintf("<%s>", ChanName(c))); }
-
- return buff;
-}
-
-static char *nv_eval(dbref thing, const char *code) {
- static char my_buff[BUFFER_LEN * 3];
- char *my_bp = my_buff;
- char *tbuf = (char *) mush_malloc(BUFFER_LEN, "nv_eval");
- char *tbuf_ptr = tbuf;
-
- strcpy(tbuf, code);
- process_expression(my_buff, &my_bp, (const char **) &tbuf,
- thing, thing, thing, PE_DEFAULT, PT_DEFAULT,
- (PE_Info *) NULL);
-
- *my_bp = '\0';
-
- mush_free((Malloc_t) tbuf_ptr, "nv_eval");
- return my_buff;
-}
-
-
+ /* Evaluate a channel lock with %0 set to the channel name.
* \param c the channel to test.
* \param p the object trying to pass the lock.
* \param type the type of channel lock to test.
MATH_FUNC(math_div)
{
/* Division, truncating to match remainder */
- int divresult, n;
+ IVAL divresult;
++ div_t q;
+ int n;
if (nptr < 1) {
safe_chr('0', buff, bp);
MATH_FUNC(math_remainder)
{
/* Remainder */
- int divresult, n;
+ IVAL divresult;
+ int n;
++ div_t r;
if (nptr < 1) {
safe_chr('0', buff, bp);
/* Signal Shit */
FUNCTION(fun_signal) {
- enum qid_flags qsig = QID_FALSE;
- int signal_r;
-
- if(!*args[0] || !*args[1])
- return;
- /* find out which signal we're using */
- if(string_prefix("kill", args[1]))
- qsig = QID_KILL;
- else if(string_prefix("freeze", args[1]))
- qsig = QID_FREEZE;
- else if(string_prefix("continue", args[1]))
- qsig = QID_CONT;
- else if(string_prefix("time", args[1]))
- qsig = QID_TIME;
- else if(string_prefix("query_t", args[1]))
- qsig = QID_QUERY_T;
- if(qsig == QID_FALSE) {
- safe_str("#-1 INVALID SIGNAL", buff, bp);
- return;
- } else if(qsig == QID_TIME && (!args[2] || !*args[2] ||
+ enum qid_flags qsig = QID_FALSE;
+ int signal_r;
+
+ if(!*args[0] || !*args[1])
+ return;
+ /* find out which signal we're using */
+ if(string_prefix("kill", args[1]))
+ qsig = QID_KILL;
+ else if(string_prefix("freeze", args[1]))
+ qsig = QID_FREEZE;
+ else if(string_prefix("continue", args[1]))
+ qsig = QID_CONT;
+ else if(string_prefix("time", args[1]))
+ qsig = QID_TIME;
+ else if(string_prefix("query_t", args[1]))
+ qsig = QID_QUERY_T;
+ if(qsig == QID_FALSE) {
+ safe_str("#-1 INVALID SIGNAL", buff, bp);
+ return;
+ } else if(qsig == QID_TIME && (!args[2] || !*args[2] ||
atoi(args[2]) < 0)) {
- safe_str("#-1 INVALID TIME ARGUMENT", buff, bp);
- return;
- }
-
- switch((signal_r = do_signal_qid(executor, atoi(args[0]), qsig, qsig == QID_TIME ? atoi(args[2]) : -1))) {
- case 0:
- safe_str("#-1 INVALID TIME ARGUMENT", buff, bp);
- break;
- case -1:
- safe_str("#-1 INVALID QID", buff, bp);
- break;
- case -2: /* we shouldn't be getting this */
- safe_str("#-1 INVALID SIGNAL", buff, bp);
- break;
- case -3:
- safe_str("#-1 PERMISSION DENIED", buff, bp);
- default:
- safe_integer(signal_r > -1 ? signal_r : 0, buff, bp);
- break;
- }
-
+ safe_str("#-1 INVALID TIME ARGUMENT", buff, bp);
+ return;
+ }
+
+ switch((signal_r = do_signal_qid(executor, atoi(args[0]), qsig, qsig == QID_TIME ? atoi(args[2]) : -1))) {
+ case 0:
+ safe_str("#-1 INVALID TIME ARGUMENT", buff, bp);
+ break;
+ case -1:
+ safe_str("#-1 INVALID QID", buff, bp);
+ break;
+ case -2: /* we shouldn't be getting this */
+ safe_str("#-1 INVALID SIGNAL", buff, bp);
+ break;
+ case -3:
+ safe_str("#-1 PERMISSION DENIED", buff, bp);
+ default:
+ safe_integer(signal_r > -1 ? signal_r : 0, buff, bp);
+ break;
+ }
-
}
FUNCTION(fun_trigger) {
}
ptr = atrname;
if ((Zone(player) != NOTHING)
- && (Zone(player) != Zone(Location(player)))) {
+ && (Zone(player) != Zone(Location(player)))) {
/* check the player's personal zone */
if (IsRoom(Zone(player))) {
- if (Location(player) != Zone(player)) {
- notify(player, T("Matches on personal zone master room:"));
- DOLIST(thing, Contents(Zone(player))) {
- if (ScanFind(player, thing)) {
- *ptr = '\0';
- notify_format(player, "%s [%d:%s]",
- unparse_object(player, thing), num, atrname);
- ptr = atrname;
- }
- }
- }
+ if (Location(player) != Zone(player)) {
+ notify(player, T("Matches on personal zone master room:"));
+ DOLIST(thing, Contents(Zone(player))) {
+ if (ScanFind(player, thing)) {
+ *ptr = '\0';
+ notify_format(player, "%s [%d:%s]",
+ unparse_object(player, thing), num, atrname);
+ ptr = atrname;
+ }
+ }
+ }
} else if (ScanFind(player, Zone(player))) {
- *ptr = '\0';
- notify_format(player, T("Matched personal zone: %s [%d:%s]"),
- unparse_object(player, Zone(player)), num, atrname);
+ *ptr = '\0';
+ notify_format(player, T("Matched personal zone: %s [%d:%s]"),
+ unparse_object(player, Zone(player)), num, atrname);
+ }
+ }
+ }
+ ptr = atrname;
+ if ((flag & CHECK_DIVISION) && GoodObject(Division(player))) {
++ /* try division tree */
++ notify(player, T("Matches on objects in the division tree:"));
++ for (thing = Division(player); GoodObject(thing);
++ thing = Division(thing)) {
++ if (ScanFind(player, thing)) {
++ *ptr = '\0';
++ notify_format(player, "%s [%d:%s]",
++ unparse_object(player, thing), num, atrname);
++ ptr = atrname;
+ }
+ }
+ }
+ ptr = atrname;
+ if ((flag & CHECK_DIVISION) && GoodObject(Division(player))) {
/* try division tree */
notify(player, T("Matches on objects in the division tree:"));
for (thing = Division(player); GoodObject(thing);
--- /dev/null
- mush_lua_env = lua_open();
+/* lua API for CobraMUSH */
+#include "config.h"
+#include <string.h>
+#include "conf.h"
+#include "dbio.h"
+#include "externs.h"
+#include "parse.h"
+#include "htab.h"
+#include "command.h"
+
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+#include "mushlua.h"
+
+extern void luaopen_cobra(lua_State *);
+static lua_State *mush_lua_env = NULL;
+void mlua_test(dbref, char *);
+
+
+void mush_lua_start() {
+
++ mush_lua_env = lua_newstate(NULL, NULL);
+ /* Load Global Values */
+
+
+ /* Load Cobra SWIG Wrappers */
+ luaopen_mush(mush_lua_env);
+
+ luaL_openlibs(mush_lua_env);
+}
+
+void mush_lua_stop() {
+
+ if(!mush_lua_env)
+ return;
+
+ lua_close(mush_lua_env);
+}
+
+/* Until we have real stuff.. this tests my lua scripts.. */
+void mlua_run(dbref enactor, char *filename) {
+ int s;
+
+ s = luaL_loadfile(mush_lua_env, tprintf("lua/%s.lua", filename));
+
+ if(s==0)
+ s = lua_pcall(mush_lua_env, 0, LUA_MULTRET, 0);
+
+ if(s != 0)
+ notify_format(enactor, "Lua Error: %s\n", lua_tostring(mush_lua_env, -1));
+}
+
+/* @lua <file> */
+COMMAND(cmd_mushlua) {
+ if(SW_ISSET(sw, SWITCH_RESTART)) {
+ mush_lua_stop();
+ mush_lua_start();
+ notify(player, "Lua Engine Restarted.");
+ } else
+ mlua_run(player, arg_left);
+}
fails_lock = !(override || eval_lock(player, target, Page_Lock));
is_haven = !override && Haven(target);
if (!Connected(target) || (Dark(target) && (is_haven || fails_lock))) {
- /* A player isn't connected if they aren't connected, or if
- * they're DARK and HAVEN, or DARK and the pagelock fails. */
- page_return(player, target, "Away", "AWAY",
- tprintf(T("%s is not connected."), Name(target)));
- if (fails_lock)
- fail_lock(player, target, Page_Lock, NULL, NOTHING);
- safe_chr(' ', tbuf, &tp);
- safe_str_space(current, tbuf, &tp);
+ /* A player isn't connected if they aren't connected, or if
+ * they're DARK and HAVEN, or DARK and the pagelock fails. */
+ page_return(player, target, "Away", "AWAY",
+ tprintf(T("%s is not connected."), Name(target)));
+ if (fails_lock)
+ fail_lock(player, target, Page_Lock, NULL, NOTHING);
+ safe_chr(' ', tbuf, &tp);
+ safe_str_space(current, tbuf, &tp);
#ifdef RPMODE_SYS
- } else if(RPMODE(player) && LEVEL(target) < 23) {
- notify(player, "You can't do that in RPMODE.");
- safe_chr(' ', tbuf, &tp);
- safe_str_space(Name(target), tbuf, &tp);
+ } else if(RPMODE(player)
+ && !(Can_RPCHAT(player) || LEVEL(target) >= 23)) {
+ notify(player, "You can't do that in RPMODE.");
+ safe_chr(' ', tbuf, &tp);
+ safe_str_space(Name(target), tbuf, &tp);
#endif
} else if (is_haven) {
- page_return(player, target, "Haven", "HAVEN",
- tprintf(T("%s is not accepting any pages."), Name(target)));
- safe_chr(' ', tbuf, &tp);
- safe_str_space(Name(target), tbuf, &tp);
+ page_return(player, target, "Haven", "HAVEN",
+ tprintf(T("%s is not accepting any pages."), Name(target)));
+ safe_chr(' ', tbuf, &tp);
+ safe_str_space(Name(target), tbuf, &tp);
} else if (fails_lock) {
- page_return(player, target, "Haven", "HAVEN",
- tprintf(T("%s is not accepting your pages."),
- Name(target)));
- fail_lock(player, target, Page_Lock, NULL, NOTHING);
- safe_chr(' ', tbuf, &tp);
- safe_str_space(Name(target), tbuf, &tp);
+ page_return(player, target, "Haven", "HAVEN",
+ tprintf(T("%s is not accepting your pages."),
+ Name(target)));
+ fail_lock(player, target, Page_Lock, NULL, NOTHING);
+ safe_chr(' ', tbuf, &tp);
+ safe_str_space(Name(target), tbuf, &tp);
- } else if(RPMODE(target) && LEVEL(player) < 23 && LEVEL(target) < 23 ) {
- page_return(player, target,
- "RPMode", "RPMODE",
- tprintf(T("%s is in RPMode and can not communicate OOCly at this moment."), Name(target)));
- safe_chr(' ', tbuf , &tp);
- safe_str_space(current, tbuf, &tp);
+ #ifdef RPMODE_SYS
+ } else if(RPMODE(target) && !(Can_RPCHAT(target) || (LEVEL(player) >= 23 && LEVEL(target) >= 23))) {
+ page_return(player, target,
+ "RPMode", "RPMODE",
+ tprintf(T("%s is in RPMode and can not communicate OOCly at this moment."), Name(target)));
+ safe_chr(' ', tbuf , &tp);
+ safe_str_space(current, tbuf, &tp);
+ #endif
- } else if(hidden(target) && !CanSee(player,target)){
- /* this is a page that appears bad, but is good */
- page_return(player, target, "Away", "AWAY",
- tprintf(T("%s is not connected."), Name(target)));
- safe_chr(' ', tbuf, &tp);
- safe_str_space(current, tbuf, &tp);
+ } else if(hidden(target) && !CanSee(player,target)){
+ /* this is a page that appears bad, but is good */
+ page_return(player, target, "Away", "AWAY",
+ tprintf(T("%s is not connected."), Name(target)));
+ safe_chr(' ', tbuf, &tp);
+ safe_str_space(current, tbuf, &tp);
almost_good[ag_count] = target;
ag_count++;
# Always present functions
use subs qw/maybemove temp_header temp_source scan_files_for_pattern/;
- # Main loop, dispatch for each command line argument.
- foreach my $command (@ARGV) {
- if ($command eq "patches") {
- make_patches;
- } elsif ($command eq "switches") {
- make_switches;
- } elsif ($command eq "commands") {
- make_cmds;
- } elsif ($command eq "functions") {
- make_funs;
- } elsif ($command eq "all") {
- make_patches;
- make_switches;
- make_cmds;
- make_funs;
- } else {
- warn "Unknown option '${command}'\n";
- }
- }
-
- # Return name of a temp file in hdrs/
- sub temp_header {
- return "hdrs/temp.$$.h";
- }
-
- # Return name of a temp file in src/
- sub temp_source {
- return "src/temp.$$.c";
- }
-
- # maybemove(file1, file2) copies file1 to file 2 if they are different,
- # otherwise just deletes file1 and leaves file2 unchanged.
- sub maybemove {
- my $from = shift;
- my $to = shift;
-
- if (compare $from, $to) {
- if (move $from, $to) {
- print "File ${to} updated.\n";
- } else {
- warn "Couldn't rename ${from} to ${to}: $!\n";
- }
- } else {
- print "File ${to} unchanged.\n";
- unlink $from;
- }
- }
-
- # scan_files_for_pattern(glob-pattern, re) searches all files matching
- # glob-pattern for lines matching re, and returns a sorted list of
- # $1's for each matching line.
- sub scan_files_for_pattern {
- my $filepattern = shift;
- my $re = shift;
- my @idents;
-
- foreach my $file (glob $filepattern) {
- open FILE, "<", $file
- or die "Cannot open ${file} for reading: $!\n";
- while (<FILE>) {
- chomp;
- push @idents, $1 if m/$re/;
- }
- close FILE;
- }
- return sort @idents;
- }
-
-
- END {
- # Make sure temp files get deleted.
- my @files = (temp_header(), temp_source());
- foreach my $file (@files) {
- unlink $file if -f $file;
- }
- }
-
- __DATA__
-
- sub make_patches {
- print "Rebuilding list of installed patches\n";
- my $tempfile = temp_header;
- my $patchfile = "hdrs/patches.h";
- my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
- open PATCHES, ">", $tempfile
- or die "Couldn't open $tempfile for writing: $!\n";
- print PATCHES $auto_msg;
- print PATCHES "#ifndef PATCHES_H\n";
- print PATCHES "#define PATCHES_H\n";
- my %patches;
- if (-d "patches") {
- foreach $file (<patches/*>) {
- next if $file =~ /(?:\.bak|\.orig|\.rej|~)$/o;
- open FILE, "<", $file
- or die "Couldn't open file '$file' for reading: $!\n";
- my $name = undef;
- my $version = undef;
- LINE: while (<FILE>) {
- chomp;
- $name = $1 if m/^# Patch name: (.*)/o;
- $version = $1 if m/^# Patch version: (.*)/o;
- if (defined $name && defined $version) {
- $patches{$name} = $version;
- last LINE;
- }
- }
- close FILE;
- }
- if (scalar keys %patches > 0) {
- print PATCHES '#define PATCHES "';
- while (my ($name, $version) = each %patches) {
- print PATCHES "$name($version) ";
- }
- print PATCHES '"', "\n";
- } else {
- print PATCHES "#undef PATCHES\n";
- }
- } else {
- print PATCHES "#undef PATCHES\n";
- }
- print PATCHES "#endif /* PATCHES_H */\n";
- close PATCHES;
-
- maybemove $tempfile, $patchfile;
- }
-
- sub make_switches {
- print "Rebuilding command switch file and header.\n";
- my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
-
- my $temphdr = temp_header;
- my $tempsrc = temp_source;
-
- open CMDHDR, "<", "hdrs/command.h" or
- die "Unable to open hdrs/command.h for reading: $!\n";
- my $numbytes = 20;
- while (<CMDHDR>) {
- if (m/^#define\s+NUM_BYTES\s+(\d+)/o) {
- $numbytes = $1;
- last;
- }
- }
- close CMDHDR;
-
- my $MAXSWITCHES = $numbytes * 8;
-
- my @switches = scan_files_for_pattern "src/SWITCHES", qr/^(.+)/;
-
- warn "Too many switches defined!\n" if length @switches > $MAXSWITCHES;
-
- open HDR, ">", $temphdr or
- die "Unable to open $temphdr for writing: $!\n";
- open SRC, ">", $tempsrc or
- die "Unable to open $tempsrc for writing: $1\n";
-
- print HDR $auto_msg;
- print HDR "#ifndef SWITCHES_H\n";
- print HDR "#define SWITCHES_H\n";
-
- print SRC $auto_msg;
- print SRC "SWITCH_VALUE switch_list[] = {\n";
-
- my $n = 1;
- foreach my $switch (@switches) {
- print HDR "#define SWITCH_${switch} ${n}\n";
- print SRC " {\"${switch}\", SWITCH_${switch}},\n";
- $n++;
- }
-
- print SRC " {NULL, 0}\n";
- print SRC "};\n";
- close SRC;
-
- print HDR "#endif /* SWITCHES_H */\n";
- close HDR;
-
- maybemove $temphdr, "hdrs/switches.h";
- maybemove $tempsrc, "src/switchinc.c";
- }
-
- # I really should combine this and make_funs into one function that does
- # the work with specific files/regexps/defines passed as arguments
-
- sub make_cmds {
- my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
-
- print "Rebuilding command prototype header.\n";
-
- my $tempfile = temp_header;
-
- my @commands =
- scan_files_for_pattern "src/*.c", qr/^\s*COMMAND\(([^\)]+)\)/;
-
- open HDR, ">", $tempfile
- or die "Can't open ${tempfile} for writing: $!\n";
-
- print HDR $auto_msg;
- print HDR "#ifndef CMDS_H\n";
- print HDR "#define CMDS_H\n";
-
- foreach my $command (@commands) {
- print HDR "COMMAND_PROTO(${command});\n";
- }
-
- print HDR "#endif /* CMDS_H */\n";
- close HDR;
-
- maybemove $tempfile, "hdrs/cmds.h";
-
- }
-
- sub make_funs {
- my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
-
- print "Rebuilding function prototype header.\n";
-
- my $tempfile = temp_header;
-
- my @functions =
- scan_files_for_pattern "src/*.c", qr/^\s*FUNCTION\(([^\)]+)\)/;
-
- open HDR, ">", $tempfile
- or die "Can't open ${tempfile} for writing: $!\n";
-
- print HDR $auto_msg;
- print HDR "#ifndef FUNS_H\n";
- print HDR "#define FUNS_H\n";
-
- foreach my $function (@functions) {
- print HDR "FUNCTION_PROTO(${function});\n";
- }
-
- print HDR "#endif /* FUNS_H */\n";
- close HDR;
-
- maybemove $tempfile, "hdrs/funs.h";
- }
-
- #!/usr/bin/perl -w
- # perl version of the old mkcmds.sh script. Runs faster by simply not running
- # a bazillion child processes. Also uses SelfLoader to avoid compiling functions
- # that are never used, since it's usually invoked with at most 1 argument.
- #
-
- use SelfLoader;
- use File::Compare;
- use File::Copy;
- use strict; # Please ma'am may I have another?
-
- # SelfLoaded functions
- use subs qw/make_patches make_switches make_cmds make_funs/;
- # Always present functions
- use subs qw/maybemove temp_header temp_source scan_files_for_pattern/;
-
--print "Starting...\n";
--
# Main loop, dispatch for each command line argument.
foreach my $command (@ARGV) {
if ($command eq "switches") {
make_switches;
} elsif ($command eq "commands") {
-- print "Commands\n";
make_cmds;
} elsif ($command eq "functions") {
make_funs;
__DATA__
sub make_switches {
-- print "Rebuilding command switch file and header.\n";
my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
my $temphdr = temp_header;
sub make_cmds {
my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
-- print "Rebuilding command prototype header.\n";
--
my $tempfile = temp_header;
--
++
my @commands =
scan_files_for_pattern "src/*.c", qr/^\s*COMMAND\s?\(([^\)]+)\)*/;
open HDR, ">", $tempfile
or die "Can't open ${tempfile} for writing: $!\n";
--
++
print HDR $auto_msg;
print HDR "#ifndef CMDS_H\n";
print HDR "#define CMDS_H\n";
sub make_funs {
my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
-- print "Rebuilding function prototype header.\n";
--
my $tempfile = temp_header;
my @functions =